summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2022-06-07 09:43:17 +0100
committerRichard Hughes <richard@hughsie.com>2022-06-08 08:05:43 +0100
commitb6cb98ee0f1fefc5831d9e3b63b727414a750567 (patch)
tree023070279c877678a93217081ea00b859a882269
parentc6c37d096f3d236e86c3073a58f7836298b05faa (diff)
downloadappstream-glib-b6cb98ee0f1fefc5831d9e3b63b727414a750567.tar.gz
Port from libsoup to libcurl
The former bumped ABI, and all sorts of crazy happens when you link in libappstream-glib into a process with the 'other' ABI. It seems the universe has settled on curl as a dep; do the same.
-rw-r--r--README.md2
-rw-r--r--client/as-util.c69
-rw-r--r--client/meson.build12
-rw-r--r--contrib/ci/Dockerfile-fedora2
-rw-r--r--contrib/libappstream-glib.spec.in4
-rw-r--r--libappstream-builder/meson.build5
-rw-r--r--libappstream-glib/as-app-validate.c86
-rw-r--r--libappstream-glib/as-utils.c1
-rw-r--r--libappstream-glib/meson.build4
-rw-r--r--meson.build4
10 files changed, 94 insertions, 95 deletions
diff --git a/README.md b/README.md
index 25924ce..e7d3b43 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ copy. To do the latter just do:
dnf install docbook-utils gettext-devel glib-devel \
gobject-introspection-devel gperf gtk-doc gtk3-devel \
- json-glib-devel libarchive-devel libsoup-devel \
+ json-glib-devel libarchive-devel libcurl-devel \
libstemmer-devel libuuid-devel libyaml-devel \
meson rpm-devel
mkdir build && cd build
diff --git a/client/as-util.c b/client/as-util.c
index b8b52fc..4c3fdaa 100644
--- a/client/as-util.c
+++ b/client/as-util.c
@@ -18,7 +18,7 @@
#include <appstream-glib.h>
#include <archive_entry.h>
#include <archive.h>
-#include <libsoup/soup.h>
+#include <curl/curl.h>
#include <locale.h>
#include <stdlib.h>
@@ -38,6 +38,7 @@ typedef struct {
GMainLoop *loop;
GCancellable *cancellable;
AsProfile *profile;
+ CURL *curl;
} AsUtilPrivate;
typedef gboolean (*AsUtilPrivateCb) (AsUtilPrivate *util,
@@ -3370,6 +3371,15 @@ as_util_mirror_screenshots_app_file (AsApp *app,
return TRUE;
}
+static size_t
+as_util_download_write_callback_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ GByteArray *buf = (GByteArray *)userdata;
+ gsize realsize = size * nmemb;
+ g_byte_array_append(buf, (const guint8 *)ptr, realsize);
+ return realsize;
+}
+
static gboolean
as_util_mirror_screenshots_app_url (AsUtilPrivate *priv,
AsApp *app,
@@ -3379,16 +3389,15 @@ as_util_mirror_screenshots_app_url (AsUtilPrivate *priv,
const gchar *output_dir,
GError **error)
{
+ CURLcode res;
gboolean is_default;
gboolean ret = TRUE;
- SoupStatus status;
+ gchar errbuf[CURL_ERROR_SIZE] = {'\0'};
g_autofree gchar *basename = NULL;
g_autofree gchar *cache_filename = NULL;
g_autoptr(AsImage) im = NULL;
g_autoptr(AsScreenshot) ss = NULL;
- g_autoptr(SoupMessage) msg = NULL;
- g_autoptr(SoupSession) session = NULL;
- g_autoptr(SoupURI) uri = NULL;
+ g_autoptr(GByteArray) buf = g_byte_array_new();
/* fonts screenshots are auto-generated */
if (as_app_get_kind (app) == AS_APP_KIND_FONT) {
@@ -3405,13 +3414,6 @@ as_util_mirror_screenshots_app_url (AsUtilPrivate *priv,
return TRUE;
}
- /* set up networking */
- session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, "appstream-util",
- SOUP_SESSION_TIMEOUT, 10,
- NULL);
- soup_session_add_feature_by_type (session,
- SOUP_TYPE_PROXY_RESOLVER_DEFAULT);
-
/* download to cache if not already added */
basename = g_path_get_basename (url);
cache_filename = g_strdup_printf ("%s/%s-%s",
@@ -3430,30 +3432,36 @@ as_util_mirror_screenshots_app_url (AsUtilPrivate *priv,
"file:// URLs like %s are not supported", url);
return FALSE;
}
- uri = soup_uri_new (url);
- if (uri == NULL) {
- g_set_error (error,
- AS_ERROR,
- AS_ERROR_FAILED,
- "Could not parse '%s' as a URL", url);
- return FALSE;
- }
- msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
as_util_app_log (app, "Downloading %s", url);
- status = soup_session_send_message (session, msg);
- if (status != SOUP_STATUS_OK) {
+
+ (void)curl_easy_setopt(priv->curl, CURLOPT_URL, url);
+ (void)curl_easy_setopt(priv->curl, CURLOPT_ERRORBUFFER, errbuf);
+ (void)curl_easy_setopt(priv->curl,
+ CURLOPT_WRITEFUNCTION,
+ as_util_download_write_callback_cb);
+ (void)curl_easy_setopt(priv->curl, CURLOPT_WRITEDATA, buf);
+ res = curl_easy_perform(priv->curl);
+ if (res != CURLE_OK) {
+ if (errbuf[0] != '\0') {
+ g_set_error (error,
+ AS_ERROR,
+ AS_ERROR_FAILED,
+ "Downloading %s failed: %s",
+ url, errbuf);
+ return FALSE;
+ }
g_set_error (error,
AS_ERROR,
AS_ERROR_FAILED,
- "Downloading failed: %s",
- soup_status_get_phrase (status));
+ "Downloading %s failed",
+ url);
return FALSE;
}
/* save new file */
ret = g_file_set_contents (cache_filename,
- msg->response_body->data,
- (gssize) msg->response_body->length,
+ (const gchar *) buf->data,
+ (gssize) buf->len,
error);
if (!ret)
return FALSE;
@@ -4437,6 +4445,11 @@ main (int argc, char *argv[])
priv = g_new0 (AsUtilPrivate, 1);
priv->profile = as_profile_new ();
+ /* networking */
+ priv->curl = curl_easy_init();
+ (void)curl_easy_setopt(priv->curl, CURLOPT_USERAGENT, "appstream-util");
+ (void)curl_easy_setopt(priv->curl, CURLOPT_CONNECTTIMEOUT, 10L);
+
/* do stuff on ctrl+c */
priv->loop = g_main_loop_new (NULL, FALSE);
priv->cancellable = g_cancellable_new ();
@@ -4752,6 +4765,8 @@ out:
if (priv != NULL) {
if (priv->cmd_array != NULL)
g_ptr_array_unref (priv->cmd_array);
+ if (priv->curl != NULL)
+ curl_easy_cleanup (priv->curl);
g_object_unref (priv->profile);
g_object_unref (priv->cancellable);
g_main_loop_unref (priv->loop);
diff --git a/client/meson.build b/client/meson.build
index d520508..fd03e62 100644
--- a/client/meson.build
+++ b/client/meson.build
@@ -10,9 +10,9 @@ if get_option('builder')
asbuilder_incdir,
],
dependencies : [
- glib,
+ gio,
gdkpixbuf,
- soup,
+ libcurl,
libarchive
],
link_with : [
@@ -33,9 +33,9 @@ appstream_util = executable(
asglib_incdir,
],
dependencies : [
- glib,
+ gio,
gdkpixbuf,
- soup,
+ libcurl,
libarchive,
],
link_with : asglib,
@@ -52,9 +52,9 @@ appstream_compose = executable(
asglib_incdir,
],
dependencies : [
- glib,
+ gio,
gdkpixbuf,
- soup,
+ libcurl,
libarchive,
],
link_with : asglib,
diff --git a/contrib/ci/Dockerfile-fedora b/contrib/ci/Dockerfile-fedora
index ba97da5..930765d 100644
--- a/contrib/ci/Dockerfile-fedora
+++ b/contrib/ci/Dockerfile-fedora
@@ -15,7 +15,7 @@ RUN dnf -y install \
gtk-doc \
json-glib-devel \
libarchive-devel \
- libsoup-devel \
+ libcurl-devel \
libstemmer-devel \
libuuid-devel \
libxslt \
diff --git a/contrib/libappstream-glib.spec.in b/contrib/libappstream-glib.spec.in
index 0013caa..3c4dd0f 100644
--- a/contrib/libappstream-glib.spec.in
+++ b/contrib/libappstream-glib.spec.in
@@ -1,5 +1,4 @@
%global glib2_version 2.45.8
-%global libsoup_version 2.51.92
%global json_glib_version 1.1.1
%global gdk_pixbuf_version 2.31.5
%define alphatag #ALPHATAG#
@@ -18,7 +17,7 @@ BuildRequires: gtk-doc
BuildRequires: gobject-introspection-devel
BuildRequires: gperf
BuildRequires: libarchive-devel
-BuildRequires: libsoup-devel >= %{libsoup_version}
+BuildRequires: libcurl-devel
BuildRequires: gdk-pixbuf2-devel >= %{gdk_pixbuf_version}
BuildRequires: gtk3-devel
BuildRequires: gettext
@@ -42,7 +41,6 @@ BuildRequires: docbook-style-xsl
Requires: gdk-pixbuf2%{?_isa} >= %{gdk_pixbuf_version}
Requires: glib2%{?_isa} >= %{glib2_version}
Requires: json-glib%{?_isa} >= %{json_glib_version}
-Requires: libsoup%{?_isa} >= %{libsoup_version}
# no longer required
Obsoletes: appdata-tools < 0.1.9
diff --git a/libappstream-builder/meson.build b/libappstream-builder/meson.build
index 79e8a74..2c7824c 100644
--- a/libappstream-builder/meson.build
+++ b/libappstream-builder/meson.build
@@ -6,11 +6,10 @@ asbuilder_cargs = [
]
deps = [
- glib,
+ gio,
gmodule,
gdkpixbuf,
libarchive,
- soup,
]
if get_option('dep11')
@@ -68,7 +67,7 @@ asb_self_test = executable(
include_directories('..'),
asglib_incdir,
],
- dependencies : [glib, gdkpixbuf, soup],
+ dependencies : [gio, gdkpixbuf],
c_args : cargs + [
'-DTESTDIRSRC="@0@/../data/tests"'.format(meson.current_source_dir()),
'-DTESTDIRBUILD="@0@/../data/tests"'.format(meson.current_build_dir()),
diff --git a/libappstream-glib/as-app-validate.c b/libappstream-glib/as-app-validate.c
index feaa466..0f9130b 100644
--- a/libappstream-glib/as-app-validate.c
+++ b/libappstream-glib/as-app-validate.c
@@ -8,8 +8,7 @@
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
-#include <libsoup/soup.h>
-#include <libsoup/soup-status.h>
+#include <curl/curl.h>
#include <string.h>
#include "as-app-private.h"
@@ -22,7 +21,7 @@ typedef struct {
AsAppValidateFlags flags;
GPtrArray *screenshot_urls;
GPtrArray *probs;
- SoupSession *session;
+ CURL *curl;
gboolean previous_para_was_short;
gchar *previous_para_was_short_str;
guint para_chars_before_list;
@@ -413,15 +412,25 @@ as_app_validate_image_url_already_exists (AsAppValidateHelper *helper,
return FALSE;
}
+static size_t
+as_app_validate_download_write_callback_cb(char *ptr, size_t size, size_t nmemb, void *userdata)
+{
+ GByteArray *buf = (GByteArray *)userdata;
+ gsize realsize = size * nmemb;
+ g_byte_array_append(buf, (const guint8 *)ptr, realsize);
+ return realsize;
+}
+
static gboolean
ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper)
{
AsImageAlphaFlags alpha_flags;
+ CURLcode res;
const gchar *url;
gboolean require_correct_aspect_ratio = FALSE;
gdouble desired_aspect = 1.777777778;
gdouble screenshot_aspect;
- guint status_code;
+ gchar errbuf[CURL_ERROR_SIZE] = {'\0'};
guint screenshot_height;
guint screenshot_width;
guint ss_size_height_max = 900;
@@ -429,9 +438,8 @@ ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper)
guint ss_size_width_max = 1600;
guint ss_size_width_min = 624;
g_autoptr(GdkPixbuf) pixbuf = NULL;
+ g_autoptr(GByteArray) buf = g_byte_array_new();
g_autoptr(GInputStream) stream = NULL;
- g_autoptr(SoupMessage) msg = NULL;
- g_autoptr(SoupURI) base_uri = NULL;
/* make the requirements more strict */
if ((helper->flags & AS_APP_VALIDATE_FLAG_STRICT) > 0) {
@@ -453,37 +461,28 @@ ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper)
/* GET file */
url = as_image_get_url (im);
g_debug ("checking %s", url);
- base_uri = soup_uri_new (url);
- if (!SOUP_URI_VALID_FOR_HTTP (base_uri)) {
+ (void)curl_easy_setopt(helper->curl, CURLOPT_URL, url);
+ (void)curl_easy_setopt(helper->curl, CURLOPT_ERRORBUFFER, errbuf);
+ (void)curl_easy_setopt(helper->curl,
+ CURLOPT_WRITEFUNCTION,
+ as_app_validate_download_write_callback_cb);
+ (void)curl_easy_setopt(helper->curl, CURLOPT_WRITEDATA, buf);
+ res = curl_easy_perform(helper->curl);
+ if (res != CURLE_OK) {
+ if (errbuf[0] != '\0') {
+ ai_app_validate_add (helper,
+ AS_PROBLEM_KIND_URL_NOT_FOUND,
+ "<screenshot> url not valid [%s]: %s", url, errbuf);
+ return FALSE;
+ }
ai_app_validate_add (helper,
AS_PROBLEM_KIND_URL_NOT_FOUND,
- "<screenshot> url not valid [%s]", url);
- return FALSE;
- }
- msg = soup_message_new_from_uri (SOUP_METHOD_GET, base_uri);
- if (msg == NULL) {
- g_warning ("Failed to setup message");
- return FALSE;
- }
-
- /* send sync */
- status_code = soup_session_send_message (helper->session, msg);
- if (SOUP_STATUS_IS_TRANSPORT_ERROR(status_code)) {
- ai_app_validate_add (helper,
- AS_PROBLEM_KIND_URL_NOT_FOUND,
- "<screenshot> failed to connect: %s [%s]",
- soup_status_get_phrase(status_code), url);
- return FALSE;
- } else if (status_code != SOUP_STATUS_OK) {
- ai_app_validate_add (helper,
- AS_PROBLEM_KIND_URL_NOT_FOUND,
- "<screenshot> failed to download (HTTP %d: %s) [%s]",
- status_code, soup_status_get_phrase(status_code), url);
+ "<screenshot> url not valid [%s]: %s", url, curl_easy_strerror(res));
return FALSE;
}
/* check if it's a zero sized file */
- if (msg->response_body->length == 0) {
+ if (buf->len == 0) {
ai_app_validate_add (helper,
AS_PROBLEM_KIND_FILE_INVALID,
"<screenshot> url is a zero length file [%s]",
@@ -492,8 +491,8 @@ ai_app_validate_image_check (AsImage *im, AsAppValidateHelper *helper)
}
/* create a buffer with the data */
- stream = g_memory_input_stream_new_from_data (msg->response_body->data,
- (gssize) msg->response_body->length,
+ stream = g_memory_input_stream_new_from_data (buf->data,
+ (gssize) buf->len,
NULL);
if (stream == NULL) {
ai_app_validate_add (helper,
@@ -993,20 +992,9 @@ as_app_validate_releases (AsApp *app, AsAppValidateHelper *helper, GError **erro
static gboolean
as_app_validate_setup_networking (AsAppValidateHelper *helper, GError **error)
{
- helper->session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT,
- "libappstream-glib",
- SOUP_SESSION_TIMEOUT,
- 5000,
- NULL);
- if (helper->session == NULL) {
- g_set_error_literal (error,
- AS_APP_ERROR,
- AS_APP_ERROR_FAILED,
- "Failed to set up networking");
- return FALSE;
- }
- soup_session_add_feature_by_type (helper->session,
- SOUP_TYPE_PROXY_RESOLVER_DEFAULT);
+ helper->curl = curl_easy_init();
+ (void)curl_easy_setopt(helper->curl, CURLOPT_USERAGENT, "libappstream-glib");
+ (void)curl_easy_setopt(helper->curl, CURLOPT_CONNECTTIMEOUT, 5L);
return TRUE;
}
@@ -1133,8 +1121,8 @@ as_app_validate_helper_free (AsAppValidateHelper *helper)
{
g_ptr_array_unref (helper->screenshot_urls);
g_free (helper->previous_para_was_short_str);
- if (helper->session != NULL)
- g_object_unref (helper->session);
+ if (helper->curl != NULL)
+ curl_easy_cleanup (helper->curl);
g_free (helper);
}
diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c
index 007a86b..d9b0f56 100644
--- a/libappstream-glib/as-utils.c
+++ b/libappstream-glib/as-utils.c
@@ -21,7 +21,6 @@
#include <string.h>
#include <archive_entry.h>
#include <archive.h>
-#include <libsoup/soup.h>
#include <stdlib.h>
#ifndef _WIN32
#ifdef __APPLE__
diff --git a/libappstream-glib/meson.build b/libappstream-glib/meson.build
index 89a007e..886f6c6 100644
--- a/libappstream-glib/meson.build
+++ b/libappstream-glib/meson.build
@@ -6,9 +6,9 @@ cargs = [
deps = [
gdkpixbuf,
- glib,
+ gio,
libarchive,
- soup,
+ libcurl,
]
if platform_win32
diff --git a/meson.build b/meson.build
index 16ae5a4..c761dad 100644
--- a/meson.build
+++ b/meson.build
@@ -63,7 +63,7 @@ plugindir = join_paths(get_option('prefix'),
'asb-plugins-' + as_plugin_version)
glib_ver = '>= 2.58.0'
-glib = dependency('glib-2.0', version : glib_ver)
+gio = dependency('gio-2.0', version : glib_ver)
gmodule = dependency('gmodule-2.0', version : glib_ver)
if platform_win32
giowindows = dependency('gio-windows-2.0', version : glib_ver)
@@ -74,7 +74,7 @@ else
uuid = dependency('uuid')
endif
libarchive = dependency('libarchive')
-soup = dependency('libsoup-2.4', version : '>= 2.51.92')
+libcurl = dependency('libcurl', version : '>= 7.56.0')
json_glib = dependency('json-glib-1.0', version : '>= 1.1.2')
gdkpixbuf = dependency('gdk-pixbuf-2.0', version : '>= 2.31.5')