diff --git a/.circleci/config.yml b/.circleci/config.yml
index e1aa3c5af..62d640ea0 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -32,14 +32,16 @@ jobs:
gcc
gcab
mingw32-nsis
+ mingw64-brotli
mingw64-gcc
mingw64-pkg-config
mingw64-glib2
+ mingw64-gnutls
mingw64-libgusb
mingw64-sqlite
mingw64-libarchive
mingw64-json-glib
- mingw64-libsoup
+ mingw64-curl
wine
- checkout
- run:
diff --git a/contrib/PKGBUILD b/contrib/PKGBUILD
index c3d3023f8..636ef880d 100644
--- a/contrib/PKGBUILD
+++ b/contrib/PKGBUILD
@@ -11,7 +11,7 @@ license=('GPL2')
depends=('libgusb' 'modemmanager' 'tpm2-tss')
makedepends=('meson' 'valgrind' 'gobject-introspection' 'gtk-doc' 'python-pillow' 'git'
'python-cairo' 'noto-fonts' 'noto-fonts-cjk' 'python-gobject' 'vala'
- 'libsoup' 'polkit' 'gcab')
+ 'curl' 'polkit' 'gcab')
pkgver() {
cd ${pkgname}
diff --git a/contrib/ci/dependencies.xml b/contrib/ci/dependencies.xml
index d6b812e54..63767e6dd 100644
--- a/contrib/ci/dependencies.xml
+++ b/contrib/ci/dependencies.xml
@@ -817,20 +817,20 @@
-
+
- libsoup
+ curl
- libsoup-devel
+ libcurl-devel
- libsoup-devel
+ libcurl-devel
- libsoup2.4-dev:s390x
+ libcurl4-gnutls-dev:s390x
diff --git a/contrib/fwupd.spec.in b/contrib/fwupd.spec.in
index e6c7dcd86..82c6a4c9f 100644
--- a/contrib/fwupd.spec.in
+++ b/contrib/fwupd.spec.in
@@ -1,7 +1,7 @@
%global glib2_version 2.45.8
%global libxmlb_version 0.1.3
%global libgusb_version 0.3.5
-%global libsoup_version 2.51.92
+%global libcurl_version 7.62.0
%global libjcat_version 0.1.0
%global systemd_version 231
%global json_glib_version 1.1.1
@@ -55,7 +55,7 @@ BuildRequires: libxmlb-devel >= %{libxmlb_version}
BuildRequires: libgcab1-devel
BuildRequires: libgudev1-devel
BuildRequires: libgusb-devel >= %{libgusb_version}
-BuildRequires: libsoup-devel >= %{libsoup_version}
+BuildRequires: libcurl-devel >= %{libcurl_version}
BuildRequires: libjcat-devel >= %{libjcat_version}
BuildRequires: polkit-devel >= 0.103
BuildRequires: sqlite-devel
@@ -112,7 +112,6 @@ Requires(postun): systemd
Requires: glib2%{?_isa} >= %{glib2_version}
Requires: libxmlb%{?_isa} >= %{libxmlb_version}
Requires: libgusb%{?_isa} >= %{libgusb_version}
-Requires: libsoup%{?_isa} >= %{libsoup_version}
Requires: bubblewrap
Requires: shared-mime-info
diff --git a/contrib/setup-win32.nsi b/contrib/setup-win32.nsi
index 83836a45f..ac3865385 100644
--- a/contrib/setup-win32.nsi
+++ b/contrib/setup-win32.nsi
@@ -48,7 +48,7 @@ Section "fwupd"
File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libnettle-7.dll"
File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libp11-kit-0.dll"
File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libpcre-1.dll"
- File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libsoup-2.4-1.dll"
+ File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libcurl-4.dll"
File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libsqlite3-0.dll"
File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libtasn1-6.dll"
File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libusb-1.0.dll"
diff --git a/libfwupd/fwupd-client.c b/libfwupd/fwupd-client.c
index 30672383a..418532a58 100644
--- a/libfwupd/fwupd-client.c
+++ b/libfwupd/fwupd-client.c
@@ -8,7 +8,7 @@
#include
#include
-#include
+#include
#ifdef HAVE_GIO_UNIX
#include
#endif
@@ -52,10 +52,14 @@ typedef struct {
gchar *host_security_id;
GDBusConnection *conn;
GDBusProxy *proxy;
- SoupSession *soup_session;
gchar *user_agent;
} FwupdClientPrivate;
+typedef struct {
+ CURL *curl;
+ curl_mime *mime;
+} FwupdCurlHelper;
+
enum {
SIGNAL_CHANGED,
SIGNAL_STATUS_CHANGED,
@@ -71,7 +75,7 @@ enum {
PROP_PERCENTAGE,
PROP_DAEMON_VERSION,
PROP_TAINTED,
- PROP_SOUP_SESSION,
+ PROP_SOUP_SESSION, /* unused ABI */
PROP_HOST_PRODUCT,
PROP_HOST_MACHINE_ID,
PROP_HOST_SECURITY_ID,
@@ -84,6 +88,20 @@ static guint signals [SIGNAL_LAST] = { 0 };
G_DEFINE_TYPE_WITH_PRIVATE (FwupdClient, fwupd_client, G_TYPE_OBJECT)
#define GET_PRIVATE(o) (fwupd_client_get_instance_private (o))
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURLU, curl_url_cleanup)
+
+static void
+fwupd_client_curl_helper_free (FwupdCurlHelper *helper)
+{
+ if (helper->curl != NULL)
+ curl_easy_cleanup (helper->curl);
+ if (helper->mime != NULL)
+ curl_mime_free (helper->mime);
+ g_free (helper);
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(FwupdCurlHelper, fwupd_client_curl_helper_free)
+
static void
fwupd_client_set_host_product (FwupdClient *self, const gchar *host_product)
{
@@ -262,12 +280,6 @@ gboolean
fwupd_client_ensure_networking (FwupdClient *self, GError **error)
{
FwupdClientPrivate *priv = GET_PRIVATE (self);
- const gchar *http_proxy;
- g_autoptr(SoupSession) session = NULL;
-
- /* already exists */
- if (priv->soup_session != NULL)
- return TRUE;
/* check the user agent is sane */
if (priv->user_agent == NULL) {
@@ -284,22 +296,62 @@ fwupd_client_ensure_networking (FwupdClient *self, GError **error)
"user agent unsuitable; fwupd version required");
return FALSE;
}
+ return TRUE;
+}
- /* create the soup session */
- session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, priv->user_agent,
- SOUP_SESSION_TIMEOUT, 60,
- NULL);
- if (session == NULL) {
+static int
+fwupd_client_progress_callback_cb (void *clientp,
+ curl_off_t dltotal,
+ curl_off_t dlnow,
+ curl_off_t ultotal,
+ curl_off_t ulnow)
+{
+ FwupdClient *self = FWUPD_CLIENT (clientp);
+
+ /* calculate percentage */
+ if (dltotal > 0 && dlnow >= 0 && dlnow <= dltotal) {
+ guint percentage = (guint) ((100 * dlnow) / dltotal);
+ g_debug ("download progress: %u%%", percentage);
+ fwupd_client_set_percentage (self, percentage);
+ } else if (ultotal > 0 && ulnow >= 0 && ulnow <= ultotal) {
+ guint percentage = (guint) ((100 * ulnow) / ultotal);
+ g_debug ("upload progress: %u%%", percentage);
+ fwupd_client_set_percentage (self, percentage);
+ }
+
+ return 0;
+}
+
+static FwupdCurlHelper *
+fwupd_client_curl_new (FwupdClient *self, GError **error)
+{
+ FwupdClientPrivate *priv = GET_PRIVATE (self);
+ const gchar *http_proxy;
+ g_autoptr(FwupdCurlHelper) helper = g_new0 (FwupdCurlHelper, 1);
+
+ /* check the user agent is sane */
+ if (!fwupd_client_ensure_networking (self, error))
+ return NULL;
+
+ /* create the session */
+ helper->curl = curl_easy_init ();
+ if (helper->curl == NULL) {
g_set_error_literal (error,
FWUPD_ERROR,
FWUPD_ERROR_INTERNAL,
"failed to setup networking");
- return FALSE;
+ return NULL;
}
+ if (g_getenv ("FWUPD_CURL_VERBOSE") != NULL)
+ curl_easy_setopt (helper->curl, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt (helper->curl, CURLOPT_XFERINFOFUNCTION, fwupd_client_progress_callback_cb);
+ curl_easy_setopt (helper->curl, CURLOPT_XFERINFODATA, self);
+ curl_easy_setopt (helper->curl, CURLOPT_USERAGENT, priv->user_agent);
+ curl_easy_setopt (helper->curl, CURLOPT_CONNECTTIMEOUT, 60L);
/* relax the SSL checks for broken corporate proxies */
if (g_getenv ("DISABLE_SSL_STRICT") != NULL)
- g_object_set (session, SOUP_SESSION_SSL_STRICT, FALSE, NULL);
+ curl_easy_setopt (helper->curl, CURLOPT_SSL_VERIFYPEER, 0L);
/* set the proxy */
http_proxy = g_getenv ("https_proxy");
@@ -309,22 +361,12 @@ fwupd_client_ensure_networking (FwupdClient *self, GError **error)
http_proxy = g_getenv ("http_proxy");
if (http_proxy == NULL)
http_proxy = g_getenv ("HTTP_PROXY");
- if (http_proxy != NULL && strlen (http_proxy) > 0) {
- g_autoptr(SoupURI) proxy_uri = soup_uri_new (http_proxy);
- if (proxy_uri == NULL) {
- g_set_error (error,
- FWUPD_ERROR,
- FWUPD_ERROR_INTERNAL,
- "invalid proxy URI: %s", http_proxy);
- return FALSE;
- }
- g_object_set (session, SOUP_SESSION_PROXY_URI, proxy_uri, NULL);
- }
+ if (http_proxy != NULL && strlen (http_proxy) > 0)
+ curl_easy_setopt (helper->curl, CURLOPT_PROXY, http_proxy);
/* this disables the double-compression of the firmware.xml.gz file */
- soup_session_remove_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
- priv->soup_session = g_steal_pointer (&session);
- return TRUE;
+ curl_easy_setopt (helper->curl, CURLOPT_HTTP_CONTENT_DECODING, 0L);
+ return g_steal_pointer (&helper);
}
static void
@@ -2234,6 +2276,13 @@ fwupd_client_install_release_download_cb (GObject *source, GAsyncResult *res, gp
g_steal_pointer (&task));
}
+static gboolean
+fwupd_client_is_url (const gchar *perhaps_url)
+{
+ g_autoptr(CURLU) h = curl_url ();
+ return curl_url_set (h, CURLUPART_URL, perhaps_url, 0) == CURLUE_OK;
+}
+
static void
fwupd_client_install_release_remote_cb (GObject *source, GAsyncResult *res, gpointer user_data)
{
@@ -2242,7 +2291,6 @@ fwupd_client_install_release_remote_cb (GObject *source, GAsyncResult *res, gpoi
g_autoptr(FwupdRemote) remote = NULL;
g_autoptr(GError) error = NULL;
g_autoptr(GTask) task = G_TASK (user_data);
- g_autoptr(SoupURI) uri = NULL;
FwupdClientInstallReleaseData *data = g_task_get_task_data (task);
GCancellable *cancellable = g_task_get_cancellable (task);
@@ -2254,8 +2302,8 @@ fwupd_client_install_release_remote_cb (GObject *source, GAsyncResult *res, gpoi
}
/* local and directory remotes may have the firmware already */
- uri = soup_uri_new (fwupd_release_get_uri (data->release));
- if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL && uri == NULL) {
+ if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL &&
+ !fwupd_client_is_url (fwupd_release_get_uri (data->release))) {
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
g_autofree gchar *path = g_path_get_dirname (fn_cache);
fn = g_build_filename (path, fwupd_release_get_uri (data->release), NULL);
@@ -3929,97 +3977,60 @@ fwupd_client_set_user_agent_for_package (FwupdClient *self,
priv->user_agent = g_string_free (str, FALSE);
}
-static void
-fwupd_client_download_chunk_cb (SoupMessage *msg, SoupBuffer *chunk, gpointer user_data)
+static size_t
+fwupd_client_download_write_callback_cb (char *ptr, size_t size, size_t nmemb, void *userdata)
{
- guint percentage;
- goffset header_size;
- goffset body_length;
- FwupdClient *self = FWUPD_CLIENT (user_data);
-
- /* if it's returning "Found" or an error, ignore the percentage */
- if (msg->status_code != SOUP_STATUS_OK) {
- g_debug ("ignoring status code %u (%s)",
- msg->status_code, msg->reason_phrase);
- return;
- }
-
- /* get data */
- body_length = msg->response_body->length;
- header_size = soup_message_headers_get_content_length (msg->response_headers);
- if (header_size < body_length)
- return;
-
- /* calculate percentage */
- percentage = (guint) ((100 * body_length) / header_size);
- g_debug ("progress: %u%%", percentage);
- fwupd_client_set_percentage (self, percentage);
+ GByteArray *buf = (GByteArray *) userdata;
+ gsize realsize = size * nmemb;
+ g_byte_array_append (buf, (const guint8 *) ptr, realsize);
+ return realsize;
}
static void
-fwupd_client_read_bytes_cb (GObject *source, GAsyncResult *res, gpointer user_data)
+fwupd_client_download_bytes_thread_cb (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- g_autoptr(GBytes) bytes = NULL;
- g_autoptr(GError) error = NULL;
- g_autoptr(GTask) task = G_TASK (user_data);
+ FwupdClient *self = FWUPD_CLIENT (source_object);
+ FwupdCurlHelper *helper = g_task_get_task_data (task);
+ CURLcode res;
+ gchar errbuf[CURL_ERROR_SIZE] = { '\0' };
+ g_autoptr(GByteArray) buf = g_byte_array_new ();
- bytes = fwupd_input_stream_read_bytes_finish (G_INPUT_STREAM (source), res, &error);
- if (bytes == NULL) {
- g_task_return_error (task, g_steal_pointer (&error));
- return;
- }
-
- /* success */
- g_task_return_pointer (task,
- g_steal_pointer (&bytes),
- (GDestroyNotify) g_bytes_unref);
-}
-
-static void
-fwupd_client_download_bytes_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
-{
- g_autoptr(GTask) task = G_TASK (user_data);
- FwupdClient *self = g_task_get_source_object (task);
- FwupdClientPrivate *priv = GET_PRIVATE (self);
- GCancellable *cancellable = g_task_get_cancellable (task);
- g_autoptr(GError) error = NULL;
- g_autoptr(GInputStream) istr = NULL;
- guint status_code = 0;
- SoupMessage *msg = g_task_get_task_data (task);
-
- /* get the result */
+ curl_easy_setopt (helper->curl, CURLOPT_ERRORBUFFER, errbuf);
+ curl_easy_setopt (helper->curl, CURLOPT_WRITEFUNCTION, fwupd_client_download_write_callback_cb);
+ curl_easy_setopt (helper->curl, CURLOPT_WRITEDATA, buf);
+ res = curl_easy_perform (helper->curl);
fwupd_client_set_status (self, FWUPD_STATUS_IDLE);
- istr = soup_session_send_finish (priv->soup_session, res, &error);
- if (istr == NULL) {
- g_task_return_error (task, g_steal_pointer (&error));
- return;
- }
-
- /* check the input stream before reading the data */
- g_object_get (msg, "status-code", &status_code, NULL);
- g_debug ("status-code was %u", status_code);
- if (status_code == 429) {
+ if (res != CURLE_OK) {
+ glong status_code = 0;
+ curl_easy_getinfo (helper->curl, CURLINFO_RESPONSE_CODE, &status_code);
+ g_debug ("status-code was %ld", status_code);
+ if (status_code == 429) {
+ g_task_return_new_error (task,
+ FWUPD_ERROR,
+ FWUPD_ERROR_INVALID_FILE,
+ "Failed to download due to server limit");
+ return;
+ }
+ if (errbuf[0] != '\0') {
+ g_task_return_new_error (task,
+ FWUPD_ERROR,
+ FWUPD_ERROR_INVALID_FILE,
+ "%s", errbuf);
+ return;
+ }
g_task_return_new_error (task,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
- "Failed to download due to server limit");
- return;
- }
- if (status_code != SOUP_STATUS_OK) {
- g_task_return_new_error (task,
- FWUPD_ERROR,
- FWUPD_ERROR_INVALID_FILE,
- "Failed to download: %s",
- soup_status_get_phrase (status_code));
- return;
- }
+ "%s", curl_easy_strerror (res));
- /* read the input stream into a GBytes, async */
- fwupd_input_stream_read_bytes_async (istr, cancellable,
- fwupd_client_read_bytes_cb,
- g_steal_pointer (&task));
+ return;
+ }
+ g_task_return_pointer (task,
+ g_byte_array_free_to_bytes (g_steal_pointer (&buf)),
+ (GDestroyNotify) g_bytes_unref);
}
/**
@@ -4049,9 +4060,8 @@ fwupd_client_download_bytes_async (FwupdClient *self,
{
FwupdClientPrivate *priv = GET_PRIVATE (self);
g_autoptr(GTask) task = NULL;
- g_autoptr(SoupMessage) msg = NULL;
- g_autoptr(SoupURI) uri = NULL;
g_autoptr(GError) error = NULL;
+ g_autoptr(FwupdCurlHelper) helper = NULL;
g_return_if_fail (FWUPD_IS_CLIENT (self));
g_return_if_fail (url != NULL);
@@ -4060,31 +4070,18 @@ fwupd_client_download_bytes_async (FwupdClient *self,
/* ensure networking set up */
task = g_task_new (self, cancellable, callback, callback_data);
- if (!fwupd_client_ensure_networking (self, &error)) {
+ helper = fwupd_client_curl_new (self, &error);
+ if (helper == NULL) {
g_task_return_error (task, g_steal_pointer (&error));
return;
}
+ curl_easy_setopt (helper->curl, CURLOPT_URL, url);
+ g_task_set_task_data (task, g_steal_pointer (&helper), (GDestroyNotify) fwupd_client_curl_helper_free);
/* download data */
g_debug ("downloading %s", url);
- uri = soup_uri_new (url);
- msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
- if (msg == NULL) {
- g_task_return_new_error (task,
- FWUPD_ERROR,
- FWUPD_ERROR_INVALID_FILE,
- "Failed to parse URI %s", url);
- return;
- }
- g_signal_connect (msg, "got-chunk",
- G_CALLBACK (fwupd_client_download_chunk_cb),
- self);
- g_task_set_task_data (task, g_object_ref (msg), (GDestroyNotify) g_object_unref);
fwupd_client_set_status (self, FWUPD_STATUS_DOWNLOADING);
- soup_session_send_async (priv->soup_session, msg,
- cancellable,
- fwupd_client_download_bytes_cb,
- g_steal_pointer (&task));
+ g_task_run_in_thread (task, fwupd_client_download_bytes_thread_cb);
}
/**
@@ -4109,42 +4106,43 @@ fwupd_client_download_bytes_finish (FwupdClient *self, GAsyncResult *res, GError
}
static void
-fwupd_client_upload_bytes_cb (GObject *source,
- GAsyncResult *res,
- gpointer user_data)
+fwupd_client_upload_bytes_thread_cb (GTask *task,
+ gpointer source_object,
+ gpointer task_data,
+ GCancellable *cancellable)
{
- g_autoptr(GTask) task = G_TASK (user_data);
- FwupdClient *self = g_task_get_source_object (task);
- FwupdClientPrivate *priv = GET_PRIVATE (self);
- GCancellable *cancellable = g_task_get_cancellable (task);
- g_autoptr(GError) error = NULL;
- g_autoptr(GInputStream) istr = NULL;
- guint status_code;
- SoupMessage *msg = g_task_get_task_data (task);
+ FwupdClient *self = FWUPD_CLIENT (source_object);
+ FwupdCurlHelper *helper = g_task_get_task_data (task);
+ CURLcode res;
+ gchar errbuf[CURL_ERROR_SIZE] = { '\0' };
+ g_autoptr(GByteArray) buf = g_byte_array_new ();
- /* get the result */
- istr = soup_session_send_finish (priv->soup_session, res, &error);
- if (istr == NULL) {
- g_task_return_error (task, g_steal_pointer (&error));
- return;
- }
-
- /* check the input stream before reading the data */
- g_object_get (msg, "status-code", &status_code, NULL);
- g_debug ("status-code was %u", status_code);
- if (!SOUP_STATUS_IS_SUCCESSFUL (status_code)) {
+ curl_easy_setopt (helper->curl, CURLOPT_ERRORBUFFER, errbuf);
+ curl_easy_setopt (helper->curl, CURLOPT_WRITEFUNCTION, fwupd_client_download_write_callback_cb);
+ curl_easy_setopt (helper->curl, CURLOPT_WRITEDATA, buf);
+ res = curl_easy_perform (helper->curl);
+ fwupd_client_set_status (self, FWUPD_STATUS_IDLE);
+ if (res != CURLE_OK) {
+ glong status_code = 0;
+ curl_easy_getinfo (helper->curl, CURLINFO_RESPONSE_CODE, &status_code);
+ g_debug ("status-code was %ld", status_code);
+ if (errbuf[0] != '\0') {
+ g_task_return_new_error (task,
+ FWUPD_ERROR,
+ FWUPD_ERROR_INVALID_FILE,
+ "%s", errbuf);
+ return;
+ }
g_task_return_new_error (task,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
- "Failed to download: %s",
- soup_status_get_phrase (status_code));
+ "%s", curl_easy_strerror (res));
+
return;
}
-
- /* read the input stream into a GBytes, async */
- fwupd_input_stream_read_bytes_async (istr, cancellable,
- fwupd_client_read_bytes_cb,
- g_steal_pointer (&task));
+ g_task_return_pointer (task,
+ g_byte_array_free_to_bytes (g_steal_pointer (&buf)),
+ (GDestroyNotify) g_bytes_unref);
}
/**
@@ -4178,8 +4176,7 @@ fwupd_client_upload_bytes_async (FwupdClient *self,
{
FwupdClientPrivate *priv = GET_PRIVATE (self);
g_autoptr(GTask) task = NULL;
- g_autoptr(SoupMessage) msg = NULL;
- g_autoptr(SoupURI) uri = NULL;
+ g_autoptr(FwupdCurlHelper) helper = NULL;
g_autoptr(GError) error = NULL;
g_return_if_fail (FWUPD_IS_CLIENT (self));
@@ -4189,48 +4186,37 @@ fwupd_client_upload_bytes_async (FwupdClient *self,
/* ensure networking set up */
task = g_task_new (self, cancellable, callback, callback_data);
- if (!fwupd_client_ensure_networking (self, &error)) {
+ helper = fwupd_client_curl_new (self, &error);
+ if (helper == NULL) {
g_task_return_error (task, g_steal_pointer (&error));
return;
}
- /* download data */
- g_debug ("downloading %s", url);
- uri = soup_uri_new (url);
-
/* build message */
if ((flags & FWUPD_CLIENT_UPLOAD_FLAG_ALWAYS_MULTIPART) > 0 ||
signature != NULL) {
- g_autoptr(SoupMultipart) mp = NULL;
- mp = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART);
- soup_multipart_append_form_string (mp, "payload", payload);
- if (signature != NULL)
- soup_multipart_append_form_string (mp, "signature", signature);
- msg = soup_form_request_new_from_multipart (url, mp);
+ curl_mimepart *part;
+ helper->mime = curl_mime_init (helper->curl);
+ curl_easy_setopt (helper->curl, CURLOPT_MIMEPOST, helper->mime);
+ part = curl_mime_addpart (helper->mime);
+ curl_mime_data (part, payload, CURL_ZERO_TERMINATED);
+ curl_mime_name (part, "payload");
+ if (signature != NULL) {
+ part = curl_mime_addpart (helper->mime);
+ curl_mime_data (part, signature, CURL_ZERO_TERMINATED);
+ curl_mime_name (part, "signature");
+ }
} else {
- msg = soup_message_new (SOUP_METHOD_POST, url);
- soup_message_set_request (msg, "application/json; charset=utf-8",
- SOUP_MEMORY_COPY, payload, strlen (payload));
+ curl_easy_setopt (helper->mime, CURLOPT_POST, 1L);
+ curl_easy_setopt (helper->curl, CURLOPT_POSTFIELDSIZE, strlen (payload));
+ curl_easy_setopt (helper->curl, CURLOPT_COPYPOSTFIELDS, payload);
}
- /* POST request */
- if (msg == NULL) {
- g_task_return_new_error (task,
- FWUPD_ERROR,
- FWUPD_ERROR_INVALID_FILE,
- "Failed to parse URI %s", url);
- return;
- }
- g_signal_connect (msg, "got-chunk",
- G_CALLBACK (fwupd_client_download_chunk_cb),
- self);
- g_task_set_task_data (task, g_object_ref (msg), (GDestroyNotify) g_object_unref);
fwupd_client_set_status (self, FWUPD_STATUS_IDLE);
g_debug ("uploading to %s", url);
- soup_session_send_async (priv->soup_session, msg,
- cancellable,
- fwupd_client_upload_bytes_cb,
- g_steal_pointer (&task));
+ curl_easy_setopt (helper->curl, CURLOPT_URL, url);
+ g_task_set_task_data (task, g_steal_pointer (&helper), (GDestroyNotify) fwupd_client_curl_helper_free);
+ g_task_run_in_thread (task, fwupd_client_upload_bytes_thread_cb);
}
/**
@@ -4269,7 +4255,7 @@ fwupd_client_get_property (GObject *object, guint prop_id,
g_value_set_boolean (value, priv->tainted);
break;
case PROP_SOUP_SESSION:
- g_value_set_object (value, priv->soup_session);
+ g_value_set_object (value, NULL);
break;
case PROP_PERCENTAGE:
g_value_set_uint (value, priv->percentage);
@@ -4309,9 +4295,6 @@ fwupd_client_set_property (GObject *object, guint prop_id,
case PROP_PERCENTAGE:
priv->percentage = g_value_get_uint (value);
break;
- case PROP_SOUP_SESSION:
- g_set_object (&priv->soup_session, g_value_get_object (value));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -4471,12 +4454,12 @@ fwupd_client_class_init (FwupdClientClass *klass)
/**
* FwupdClient:soup-session:
*
- * The libsoup session.
+ * The libsoup session, now unused.
*
* Since: 1.4.5
*/
- pspec = g_param_spec_object ("soup-session", NULL, NULL, SOUP_TYPE_SESSION,
- G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
+ pspec = g_param_spec_object ("soup-session", NULL, NULL, G_TYPE_OBJECT,
+ G_PARAM_READABLE | G_PARAM_STATIC_NAME);
g_object_class_install_property (object_class, PROP_SOUP_SESSION, pspec);
/**
@@ -4533,8 +4516,6 @@ fwupd_client_finalize (GObject *object)
g_object_unref (priv->conn);
if (priv->proxy != NULL)
g_object_unref (priv->proxy);
- if (priv->soup_session != NULL)
- g_object_unref (priv->soup_session);
G_OBJECT_CLASS (fwupd_client_parent_class)->finalize (object);
}
diff --git a/libfwupd/fwupd-remote.c b/libfwupd/fwupd-remote.c
index f63a2668d..7122b5400 100644
--- a/libfwupd/fwupd-remote.c
+++ b/libfwupd/fwupd-remote.c
@@ -6,7 +6,7 @@
#include "config.h"
-#include
+#include
#include
#include "fwupd-deprecated.h"
@@ -67,6 +67,10 @@ enum {
G_DEFINE_TYPE_WITH_PRIVATE (FwupdRemote, fwupd_remote, G_TYPE_OBJECT)
#define GET_PRIVATE(o) (fwupd_remote_get_instance_private (o))
+typedef gchar curlptr;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(curlptr, curl_free)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURLU, curl_url_cleanup)
+
static void
fwupd_remote_set_username (FwupdRemote *self, const gchar *username)
{
@@ -150,11 +154,11 @@ fwupd_remote_set_filename_source (FwupdRemote *self, const gchar *filename_sourc
priv->filename_source = g_strdup (filename_source);
}
-static SoupURI *
+static CURLU *
fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error)
{
FwupdRemotePrivate *priv = GET_PRIVATE (self);
- SoupURI *uri;
+ g_autoptr(CURLU) uri = curl_url ();
g_return_val_if_fail (FWUPD_IS_REMOTE (self), NULL);
g_return_val_if_fail (url != NULL, NULL);
@@ -162,48 +166,43 @@ fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error)
/* create URI, substituting if required */
if (priv->firmware_base_uri != NULL) {
- g_autoptr(SoupURI) uri_tmp = NULL;
g_autofree gchar *basename = NULL;
- g_autofree gchar *url2 = NULL;
- uri_tmp = soup_uri_new (url);
- if (uri_tmp == NULL) {
+ g_autofree gchar *path_new = NULL;
+ g_autoptr(curlptr) path = NULL;
+ g_autoptr(CURLU) uri_tmp = curl_url ();
+ if (curl_url_set (uri_tmp, CURLUPART_URL, url, 0) != CURLUE_OK) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
- "Failed to parse URI '%s'", url);
- return NULL;
- }
- basename = g_path_get_basename (soup_uri_get_path (uri_tmp));
- url2 = g_build_filename (priv->firmware_base_uri, basename, NULL);
- uri = soup_uri_new (url2);
- if (uri == NULL) {
- g_set_error (error,
- FWUPD_ERROR,
- FWUPD_ERROR_INVALID_FILE,
- "Failed to parse URI '%s'", url2);
+ "Failed to parse url '%s'", url);
return NULL;
}
+ curl_url_get (uri_tmp, CURLUPART_PATH, &path, 0);
+ basename = g_path_get_basename (path);
+ path_new = g_build_filename (priv->firmware_base_uri, basename, NULL);
+ curl_url_set (uri, CURLUPART_URL, path_new, 0);
/* use the base URI of the metadata to build the full path */
} else if (g_strstr_len (url, -1, "/") == NULL) {
g_autofree gchar *basename = NULL;
- g_autofree gchar *path = NULL;
- uri = soup_uri_new (priv->metadata_uri);
- if (uri == NULL) {
+ g_autofree gchar *path_new = NULL;
+ g_autoptr(curlptr) path = NULL;
+ if (curl_url_set (uri, CURLUPART_URL, priv->metadata_uri, 0) != CURLUE_OK) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
- "Failed to parse metadata URI '%s'", url);
+ "Failed to parse url '%s'",
+ priv->metadata_uri);
return NULL;
}
- basename = g_path_get_dirname (soup_uri_get_path (uri));
- path = g_build_filename (basename, url, NULL);
- soup_uri_set_path (uri, path);
+ curl_url_get (uri, CURLUPART_PATH, &path, 0);
+ basename = g_path_get_dirname (path);
+ path_new = g_build_filename (basename, url, NULL);
+ curl_url_set (uri, CURLUPART_URL, path_new, 0);
/* a normal URI */
} else {
- uri = soup_uri_new (url);
- if (uri == NULL) {
+ if (curl_url_set (uri, CURLUPART_URL, url, 0) != CURLUE_OK) {
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
@@ -214,10 +213,10 @@ fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error)
/* set the username and password */
if (priv->username != NULL)
- soup_uri_set_user (uri, priv->username);
+ curl_url_set (uri, CURLUPART_USER, priv->username, 0);
if (priv->password != NULL)
- soup_uri_set_password (uri, priv->password);
- return uri;
+ curl_url_set (uri, CURLUPART_PASSWORD, priv->password, 0);
+ return g_steal_pointer (&uri);
}
/* note, this has to be set before username and password */
@@ -225,12 +224,6 @@ static void
fwupd_remote_set_metadata_uri (FwupdRemote *self, const gchar *metadata_uri)
{
FwupdRemotePrivate *priv = GET_PRIVATE (self);
- g_autoptr(SoupURI) uri = NULL;
-
- /* build the URI */
- uri = soup_uri_new (metadata_uri);
- if (uri == NULL)
- return;
/* save this so we can export the object as a GVariant */
priv->metadata_uri = g_strdup (metadata_uri);
@@ -872,10 +865,12 @@ fwupd_remote_get_checksum (FwupdRemote *self)
gchar *
fwupd_remote_build_firmware_uri (FwupdRemote *self, const gchar *url, GError **error)
{
- g_autoptr(SoupURI) uri = fwupd_remote_build_uri (self, url, error);
+ g_autoptr(curlptr) tmp = NULL;
+ g_autoptr(CURLU) uri = fwupd_remote_build_uri (self, url, error);
if (uri == NULL)
return NULL;
- return soup_uri_to_string (uri, FALSE);
+ curl_url_get (uri, CURLUPART_URL, &tmp, 0);
+ return g_strdup (tmp);
}
/**
diff --git a/libfwupd/meson.build b/libfwupd/meson.build
index f31581497..a303a8d63 100644
--- a/libfwupd/meson.build
+++ b/libfwupd/meson.build
@@ -32,7 +32,7 @@ install_headers([
libfwupd_deps = [
giounix,
- soup,
+ libcurl,
libjcat,
libjsonglib,
]
@@ -122,19 +122,18 @@ if get_option('introspection')
header : 'fwupd.h',
dependencies : [
giounix,
- soup,
+ libcurl,
],
includes : [
'Gio-2.0',
'GObject-2.0',
- 'Soup-2.4',
],
install : true
)
gnome.generate_vapi('fwupd',
sources : fwupd_gir[0],
- packages : ['gio-2.0', 'libsoup-2.4'],
+ packages : ['gio-2.0'],
install : true,
)
@@ -178,7 +177,7 @@ if get_option('tests')
],
dependencies : [
gio,
- soup,
+ libcurl,
libjsonglib,
],
link_with : fwupd,
diff --git a/libfwupdplugin/meson.build b/libfwupdplugin/meson.build
index ba8e6bc4d..43517d227 100644
--- a/libfwupdplugin/meson.build
+++ b/libfwupdplugin/meson.build
@@ -143,7 +143,6 @@ fwupdplugin_pkgg.generate(
'json-glib-1.0',
'libarchive',
'libgcab-1.0',
- 'libsoup-2.4',
'xmlb',
'jcat',
],
diff --git a/meson.build b/meson.build
index 69b526528..5fc77a284 100644
--- a/meson.build
+++ b/meson.build
@@ -208,7 +208,7 @@ endif
libjcat = dependency('jcat', version : '>= 0.1.0', fallback : ['libjcat', 'libjcat_dep'])
libjsonglib = dependency('json-glib-1.0', version : '>= 1.1.1')
valgrind = dependency('valgrind', required: false)
-soup = dependency('libsoup-2.4', version : '>= 2.51.92')
+libcurl = dependency('libcurl', version : '>= 7.62.0')
if build_daemon
if get_option('polkit')
polkit = dependency('polkit-gobject-1', version : '>= 0.103')
@@ -448,7 +448,6 @@ if build_standalone
plugin_deps += giounix
plugin_deps += gmodule
plugin_deps += gusb
- plugin_deps += soup
plugin_deps += libarchive
plugin_deps += gudev
plugin_deps += libjsonglib
diff --git a/plugins/redfish/fu-redfish-client.c b/plugins/redfish/fu-redfish-client.c
index 9b708f975..6d770932a 100644
--- a/plugins/redfish/fu-redfish-client.c
+++ b/plugins/redfish/fu-redfish-client.c
@@ -7,7 +7,7 @@
#include "config.h"
#include
-#include
+#include
#include
#include "fwupd-error.h"
@@ -22,14 +22,11 @@
struct _FuRedfishClient
{
GObject parent_instance;
- SoupSession *session;
+ CURL *curl;
gchar *hostname;
guint port;
- gchar *username;
- gchar *password;
gchar *update_uri_path;
gchar *push_uri_path;
- gboolean auth_created;
gboolean use_https;
gboolean cacheck;
GPtrArray *devices;
@@ -37,62 +34,57 @@ struct _FuRedfishClient
G_DEFINE_TYPE (FuRedfishClient, fu_redfish_client, G_TYPE_OBJECT)
-static void
-fu_redfish_client_set_auth (FuRedfishClient *self, SoupURI *uri,
- SoupMessage *msg)
+typedef gchar curlptr;
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(curlptr, curl_free)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURLU, curl_url_cleanup)
+
+static size_t
+fu_redfish_client_fetch_data_cb (char *ptr, size_t size, size_t nmemb, void *userdata)
{
- if ((self->username != NULL && self->password != NULL) &&
- self->auth_created == FALSE) {
- /*
- * Some redfish implementations miss WWW-Authenticate
- * header for a 401 response, and SoupAuthManager couldn't
- * generate SoupAuth accordingly. Since DSP0266 makes
- * Basic Authorization a requirement for redfish, it shall be
- * safe to use Basic Auth for all redfish implementations.
- */
- SoupAuthManager *manager = SOUP_AUTH_MANAGER (soup_session_get_feature (self->session, SOUP_TYPE_AUTH_MANAGER));
- g_autoptr(SoupAuth) auth = soup_auth_new (SOUP_TYPE_AUTH_BASIC,
- msg, "Basic");
- soup_auth_authenticate (auth, self->username, self->password);
- soup_auth_manager_use_auth (manager, uri, auth);
- self->auth_created = TRUE;
- }
+ GByteArray *buf = (GByteArray *) userdata;
+ gsize realsize = size * nmemb;
+ g_byte_array_append (buf, (const guint8 *) ptr, realsize);
+ return realsize;
}
static GBytes *
fu_redfish_client_fetch_data (FuRedfishClient *self, const gchar *uri_path, GError **error)
{
- guint status_code;
- g_autoptr(SoupMessage) msg = NULL;
- g_autoptr(SoupURI) uri = NULL;
+ CURLcode res;
+ g_autofree gchar *port = g_strdup_printf ("%u", self->port);
+ g_autoptr(CURLU) uri = NULL;
+ g_autoptr(GByteArray) buf = g_byte_array_new ();
/* create URI */
- uri = soup_uri_new (NULL);
- soup_uri_set_scheme (uri, self->use_https ? "https" : "http");
- soup_uri_set_path (uri, uri_path);
- soup_uri_set_host (uri, self->hostname);
- soup_uri_set_port (uri, self->port);
- msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
- if (msg == NULL) {
- g_autofree gchar *tmp = soup_uri_to_string (uri, FALSE);
- g_set_error (error,
- FWUPD_ERROR,
- FWUPD_ERROR_INVALID_FILE,
- "failed to create message for URI %s", tmp);
+ uri = curl_url ();
+ curl_url_set (uri, CURLU_DEFAULT_SCHEME, self->use_https ? "https" : "http", 0);
+ curl_url_set (uri, CURLUPART_PATH, uri_path, 0);
+ curl_url_set (uri, CURLUPART_HOST, self->hostname, 0);
+ curl_url_set (uri, CURLUPART_PORT, port, 0);
+ if (curl_easy_setopt (self->curl, CURLOPT_CURLU, uri) != CURLE_OK) {
+ g_set_error_literal (error,
+ FWUPD_ERROR,
+ FWUPD_ERROR_INVALID_FILE,
+ "failed to create message for URI");
return NULL;
}
- fu_redfish_client_set_auth (self, uri, msg);
- status_code = soup_session_send_message (self->session, msg);
- if (status_code != SOUP_STATUS_OK) {
- g_autofree gchar *tmp = soup_uri_to_string (uri, FALSE);
+ curl_easy_setopt (self->curl, CURLOPT_WRITEFUNCTION, fu_redfish_client_fetch_data_cb);
+ curl_easy_setopt (self->curl, CURLOPT_WRITEDATA, buf);
+ res = curl_easy_perform (self->curl);
+ if (res != CURLE_OK) {
+ glong status_code = 0;
+ g_autoptr(curlptr) uri_str = NULL;
+ curl_easy_getinfo (self->curl, CURLINFO_RESPONSE_CODE, &status_code);
+ curl_url_get (uri, CURLUPART_URL, &uri_str, 0);
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"failed to download %s: %s",
- tmp, soup_status_get_phrase (status_code));
+ uri_str, curl_easy_strerror (res));
return NULL;
}
- return g_bytes_new (msg->response_body->data, msg->response_body->length);
+
+ return g_byte_array_free_to_bytes (g_steal_pointer (&buf));
}
static gboolean
@@ -569,19 +561,19 @@ fu_redfish_client_set_smbios_interfaces (FuRedfishClient *self,
return TRUE;
}
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(curl_mime, curl_mime_free)
+
gboolean
fu_redfish_client_update (FuRedfishClient *self, FuDevice *device, GBytes *blob_fw,
GError **error)
{
+ CURLcode res;
FwupdRelease *release;
+ curl_mimepart *part;
g_autofree gchar *filename = NULL;
-
- guint status_code;
- g_autoptr(SoupMessage) msg = NULL;
- g_autoptr(SoupURI) uri = NULL;
- g_autoptr(SoupMultipart) multipart = NULL;
- g_autoptr(SoupBuffer) buffer = NULL;
- g_autofree gchar *uri_str = NULL;
+ g_autofree gchar *port = g_strdup_printf ("%u", self->port);
+ g_autoptr(CURLU) uri = curl_url ();
+ g_autoptr(curl_mime) mime = curl_mime_init (self->curl);
/* Get the update version */
release = fwupd_device_get_release_default (FWUPD_DEVICE (device));
@@ -595,38 +587,35 @@ fu_redfish_client_update (FuRedfishClient *self, FuDevice *device, GBytes *blob_
}
/* create URI */
- uri = soup_uri_new (NULL);
- soup_uri_set_scheme (uri, self->use_https ? "https" : "http");
- soup_uri_set_path (uri, self->push_uri_path);
- soup_uri_set_host (uri, self->hostname);
- soup_uri_set_port (uri, self->port);
- uri_str = soup_uri_to_string (uri, FALSE);
-
- /* Create the multipart request */
- multipart = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART);
- buffer = soup_buffer_new (SOUP_MEMORY_COPY,
- g_bytes_get_data (blob_fw, NULL),
- g_bytes_get_size (blob_fw));
- soup_multipart_append_form_file (multipart, filename, filename,
- "application/octet-stream",
- buffer);
- msg = soup_form_request_new_from_multipart (uri_str, multipart);
- if (msg == NULL) {
- g_set_error (error,
- FWUPD_ERROR,
- FWUPD_ERROR_INVALID_FILE,
- "failed to create message for URI %s", uri_str);
+ curl_url_set (uri, CURLU_DEFAULT_SCHEME, self->use_https ? "https" : "http", 0);
+ curl_url_set (uri, CURLUPART_PATH, self->push_uri_path, 0);
+ curl_url_set (uri, CURLUPART_HOST, self->hostname, 0);
+ curl_url_set (uri, CURLUPART_PORT, port, 0);
+ if (curl_easy_setopt (self->curl, CURLOPT_CURLU, uri) != CURLE_OK) {
+ g_set_error_literal (error,
+ FWUPD_ERROR,
+ FWUPD_ERROR_INVALID_FILE,
+ "failed to create message for URI");
return FALSE;
}
- fu_redfish_client_set_auth (self, uri, msg);
- status_code = soup_session_send_message (self->session, msg);
- if (status_code != SOUP_STATUS_OK) {
+
+ /* Create the multipart request */
+ curl_easy_setopt (self->curl, CURLOPT_MIMEPOST, mime);
+ part = curl_mime_addpart (mime);
+ curl_mime_data (part, g_bytes_get_data (blob_fw, NULL), g_bytes_get_size (blob_fw));
+ curl_mime_type (part, "application/octet-stream");
+ res = curl_easy_perform (self->curl);
+ if (res != CURLE_OK) {
+ glong status_code = 0;
+ g_autoptr(curlptr) uri_str = NULL;
+ curl_easy_getinfo (self->curl, CURLINFO_RESPONSE_CODE, &status_code);
+ curl_url_get (uri, CURLUPART_URL, &uri_str, 0);
g_set_error (error,
FWUPD_ERROR,
FWUPD_ERROR_INVALID_FILE,
"failed to upload %s to %s: %s",
filename, uri_str,
- soup_status_get_phrase (status_code));
+ curl_easy_strerror (res));
return FALSE;
}
@@ -662,24 +651,12 @@ fu_redfish_client_setup (FuRedfishClient *self, GBytes *smbios_table, GError **e
return FALSE;
}
- /* create the soup session */
+ /* setup networking */
user_agent = g_strdup_printf ("%s/%s", PACKAGE_NAME, PACKAGE_VERSION);
- self->session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, user_agent,
- SOUP_SESSION_TIMEOUT, 60,
- NULL);
- if (self->session == NULL) {
- g_set_error_literal (error,
- FWUPD_ERROR,
- FWUPD_ERROR_INTERNAL,
- "failed to setup networking");
- return FALSE;
- }
-
- if (self->cacheck == FALSE) {
- g_object_set (G_OBJECT (self->session),
- SOUP_SESSION_SSL_STRICT, FALSE,
- NULL);
- }
+ curl_easy_setopt (self->curl, CURLOPT_USERAGENT , user_agent);
+ curl_easy_setopt (self->curl, CURLOPT_CONNECTTIMEOUT, 60L);
+ if (self->cacheck == FALSE)
+ curl_easy_setopt (self->curl, CURLOPT_SSL_VERIFYPEER , 0L);
/* this is optional */
if (smbios_table != NULL) {
@@ -700,10 +677,6 @@ fu_redfish_client_setup (FuRedfishClient *self, GBytes *smbios_table, GError **e
g_debug ("Hostname: %s", self->hostname);
if (self->port != 0)
g_debug ("Port: %u", self->port);
- if (self->username != NULL)
- g_debug ("Username: %s", self->username);
- if (self->password != NULL)
- g_debug ("Password: %s", self->password);
/* try to connect */
blob = fu_redfish_client_fetch_data (self, "/redfish/v1/", error);
@@ -800,28 +773,24 @@ fu_redfish_client_set_cacheck (FuRedfishClient *self, gboolean cacheck)
void
fu_redfish_client_set_username (FuRedfishClient *self, const gchar *username)
{
- g_free (self->username);
- self->username = g_strdup (username);
+ curl_easy_setopt (self->curl, CURLOPT_USERNAME, username);
}
void
fu_redfish_client_set_password (FuRedfishClient *self, const gchar *password)
{
- g_free (self->password);
- self->password = g_strdup (password);
+ curl_easy_setopt (self->curl, CURLOPT_PASSWORD, password);
}
static void
fu_redfish_client_finalize (GObject *object)
{
FuRedfishClient *self = FU_REDFISH_CLIENT (object);
- if (self->session != NULL)
- g_object_unref (self->session);
+ if (self->curl != NULL)
+ curl_easy_cleanup (self->curl);
g_free (self->update_uri_path);
g_free (self->push_uri_path);
g_free (self->hostname);
- g_free (self->username);
- g_free (self->password);
g_ptr_array_unref (self->devices);
G_OBJECT_CLASS (fu_redfish_client_parent_class)->finalize (object);
}
@@ -837,6 +806,11 @@ static void
fu_redfish_client_init (FuRedfishClient *self)
{
self->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
+ self->curl = curl_easy_init ();
+
+ /* since DSP0266 makes Basic Authorization a requirement,
+ * it is safe to use Basic Auth for all implementations */
+ curl_easy_setopt (self->curl, CURLOPT_HTTPAUTH, (glong) CURLAUTH_BASIC);
}
FuRedfishClient *
diff --git a/plugins/redfish/meson.build b/plugins/redfish/meson.build
index 927627918..205d1394c 100644
--- a/plugins/redfish/meson.build
+++ b/plugins/redfish/meson.build
@@ -21,6 +21,7 @@ shared_module('fu_plugin_redfish',
c_args : cargs,
dependencies : [
plugin_deps,
+ libcurl,
libjsonglib,
],
)
@@ -45,6 +46,7 @@ if get_option('tests')
],
dependencies : [
plugin_deps,
+ libcurl,
libjsonglib,
],
link_with : [
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 65205bba9..a42ec3ffa 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -35,6 +35,8 @@ apps:
command: fwupdagent.wrapper
parts:
+ curl:
+ source: https://curl.se/download/curl-7.73.0.tar.bz2
tpm2-tss:
plugin: autotools
source: https://github.com/tpm2-software/tpm2-tss/releases/download/2.3.0/tpm2-tss-2.3.0.tar.gz
@@ -211,7 +213,6 @@ parts:
- libpci-dev
- libpolkit-gobject-1-dev
- libsmbios-dev
- - libsoup2.4-dev
- libsqlite3-dev
- libsystemd-dev
- locales
@@ -232,7 +233,6 @@ parts:
- libjson-glib-1.0-0
- libpolkit-gobject-1-0
- libsmbios-c2
- - libsoup2.4-1
- glib-networking
- libglib2.0-bin
prime:
@@ -272,7 +272,7 @@ parts:
- -usr/lib/*/pkgconfig
# we don't want system gnutls leaking in
- -usr/lib/*/libgnutls*
- after: [meson, build-introspection, modemmanager, libmbim, libqmi, tpm2-tss, gnutls]
+ after: [meson, build-introspection, modemmanager, libmbim, libqmi, tpm2-tss, gnutls, curl]
fix-bash-completion:
plugin: make
source: contrib/snap/fix-bash-completion
diff --git a/src/fu-tool.c b/src/fu-tool.c
index f35847492..f6bb3c12e 100644
--- a/src/fu-tool.c
+++ b/src/fu-tool.c
@@ -18,7 +18,6 @@
#include
#include
#include
-#include
#include
#include "fu-device-private.h"
@@ -912,13 +911,11 @@ static gchar *
fu_util_download_if_required (FuUtilPrivate *priv, const gchar *perhapsfn, GError **error)
{
g_autofree gchar *filename = NULL;
- g_autoptr(SoupURI) uri = NULL;
/* a local file */
- uri = soup_uri_new (perhapsfn);
if (g_file_test (perhapsfn, G_FILE_TEST_EXISTS))
return g_strdup (perhapsfn);
- if (uri == NULL)
+ if (!fu_util_is_url (perhapsfn))
return g_strdup (perhapsfn);
/* download the firmware to a cachedir */
@@ -1079,7 +1076,6 @@ fu_util_install_release (FuUtilPrivate *priv, FwupdRelease *rel, GError **error)
const gchar *remote_id;
const gchar *uri_tmp;
g_auto(GStrv) argv = NULL;
- g_autoptr(SoupURI) uri = NULL;
uri_tmp = fwupd_release_get_uri (rel);
if (uri_tmp == NULL) {
@@ -1107,8 +1103,8 @@ fu_util_install_release (FuUtilPrivate *priv, FwupdRelease *rel, GError **error)
argv = g_new0 (gchar *, 2);
/* local remotes may have the firmware already */
- uri = soup_uri_new (uri_tmp);
- if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL && uri == NULL) {
+ if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL &&
+ !fu_util_is_url (uri_tmp)) {
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
g_autofree gchar *path = g_path_get_dirname (fn_cache);
argv[0] = g_build_filename (path, uri_tmp, NULL);
diff --git a/src/fu-util-common.c b/src/fu-util-common.c
index 39b0338ad..d4b430101 100644
--- a/src/fu-util-common.c
+++ b/src/fu-util-common.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include "fu-common.h"
#include "fu-device-private.h"
@@ -2007,3 +2008,12 @@ fu_util_show_unsupported_warn (void)
g_printerr ("%s %s\n", fmt, _("This package has not been validated, it may not work properly."));
#endif
}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(CURLU, curl_url_cleanup)
+
+gboolean
+fu_util_is_url (const gchar *perhaps_url)
+{
+ g_autoptr(CURLU) h = curl_url ();
+ return curl_url_set (h, CURLUPART_URL, perhaps_url, 0) == CURLUE_OK;
+}
diff --git a/src/fu-util-common.h b/src/fu-util-common.h
index 287178c59..bc3a3b516 100644
--- a/src/fu-util-common.h
+++ b/src/fu-util-common.h
@@ -8,7 +8,6 @@
#include
#include
-#include
/* this is only valid for tools */
#define FWUPD_ERROR_INVALID_ARGS (FWUPD_ERROR_LAST+1)
@@ -119,3 +118,4 @@ gboolean fu_util_switch_branch_warning (FwupdDevice *dev,
gboolean assume_yes,
GError **error);
void fu_util_show_unsupported_warn (void);
+gboolean fu_util_is_url (const gchar *perhaps_url);
diff --git a/src/fu-util.c b/src/fu-util.c
index 7c12440a8..82e676a5d 100644
--- a/src/fu-util.c
+++ b/src/fu-util.c
@@ -584,13 +584,11 @@ fu_util_download_if_required (FuUtilPrivate *priv, const gchar *perhapsfn, GErro
{
g_autofree gchar *filename = NULL;
g_autoptr(GBytes) blob = NULL;
- g_autoptr(SoupURI) uri = NULL;
/* a local file */
if (g_file_test (perhapsfn, G_FILE_TEST_EXISTS))
return g_strdup (perhapsfn);
- uri = soup_uri_new (perhapsfn);
- if (uri == NULL)
+ if (!fu_util_is_url (perhapsfn))
return g_strdup (perhapsfn);
/* download the firmware to a cachedir */
diff --git a/src/meson.build b/src/meson.build
index a8aca163a..68f787bf9 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -34,11 +34,11 @@ fwupdmgr = executable(
fwupdplugin_incdir,
],
dependencies : [
+ libcurl,
libxmlb,
giounix,
gudev,
gusb,
- soup,
sqlite,
libarchive,
libjsonglib,
@@ -67,11 +67,11 @@ fwupdagent = executable(
fwupdplugin_incdir,
],
dependencies : [
+ libcurl,
libxmlb,
giounix,
gudev,
gusb,
- soup,
libjsonglib,
],
link_with : [
@@ -102,9 +102,9 @@ fwupdoffline = executable(
giounix,
gudev,
gusb,
+ libcurl,
libjsonglib,
libxmlb,
- soup,
sqlite,
],
link_with : [
@@ -153,6 +153,7 @@ fwupdtool = executable(
fwupdplugin_incdir,
],
dependencies : [
+ libcurl,
libjcat,
libxmlb,
libgcab,
@@ -160,7 +161,6 @@ fwupdtool = executable(
gmodule,
gudev,
gusb,
- soup,
sqlite,
valgrind,
libarchive,
@@ -263,7 +263,6 @@ executable(
gmodule,
gudev,
gusb,
- soup,
sqlite,
valgrind,
libarchive,
@@ -323,7 +322,6 @@ if get_option('tests')
gmodule,
gudev,
gusb,
- soup,
sqlite,
valgrind,
libarchive,