mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-07 10:27:36 +00:00
Switch from libsoup to libcurl
The former drags on glib-networking and then gsettings-desktop-schemas, which add over 5Mb to the minimal IoT and CoreOS composes. Everything already uses libcurl (even NetworkManager!) and so this is an easy way to reduce image size.
This commit is contained in:
parent
a6e6085365
commit
3a73c342ba
@ -32,14 +32,16 @@ jobs:
|
|||||||
gcc
|
gcc
|
||||||
gcab
|
gcab
|
||||||
mingw32-nsis
|
mingw32-nsis
|
||||||
|
mingw64-brotli
|
||||||
mingw64-gcc
|
mingw64-gcc
|
||||||
mingw64-pkg-config
|
mingw64-pkg-config
|
||||||
mingw64-glib2
|
mingw64-glib2
|
||||||
|
mingw64-gnutls
|
||||||
mingw64-libgusb
|
mingw64-libgusb
|
||||||
mingw64-sqlite
|
mingw64-sqlite
|
||||||
mingw64-libarchive
|
mingw64-libarchive
|
||||||
mingw64-json-glib
|
mingw64-json-glib
|
||||||
mingw64-libsoup
|
mingw64-curl
|
||||||
wine
|
wine
|
||||||
- checkout
|
- checkout
|
||||||
- run:
|
- run:
|
||||||
|
@ -11,7 +11,7 @@ license=('GPL2')
|
|||||||
depends=('libgusb' 'modemmanager' 'tpm2-tss')
|
depends=('libgusb' 'modemmanager' 'tpm2-tss')
|
||||||
makedepends=('meson' 'valgrind' 'gobject-introspection' 'gtk-doc' 'python-pillow' 'git'
|
makedepends=('meson' 'valgrind' 'gobject-introspection' 'gtk-doc' 'python-pillow' 'git'
|
||||||
'python-cairo' 'noto-fonts' 'noto-fonts-cjk' 'python-gobject' 'vala'
|
'python-cairo' 'noto-fonts' 'noto-fonts-cjk' 'python-gobject' 'vala'
|
||||||
'libsoup' 'polkit' 'gcab')
|
'curl' 'polkit' 'gcab')
|
||||||
|
|
||||||
pkgver() {
|
pkgver() {
|
||||||
cd ${pkgname}
|
cd ${pkgname}
|
||||||
|
@ -817,20 +817,20 @@
|
|||||||
<package variant="x86_64" />
|
<package variant="x86_64" />
|
||||||
</distro>
|
</distro>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency type="build" id="libsoup2.4-dev">
|
<dependency type="build" id="libcurl4-gnutls-dev">
|
||||||
<distro id="arch">
|
<distro id="arch">
|
||||||
<package>libsoup</package>
|
<package>curl</package>
|
||||||
</distro>
|
</distro>
|
||||||
<distro id="centos">
|
<distro id="centos">
|
||||||
<package>libsoup-devel</package>
|
<package>libcurl-devel</package>
|
||||||
</distro>
|
</distro>
|
||||||
<distro id="fedora">
|
<distro id="fedora">
|
||||||
<package>libsoup-devel</package>
|
<package>libcurl-devel</package>
|
||||||
</distro>
|
</distro>
|
||||||
<distro id="debian">
|
<distro id="debian">
|
||||||
<control />
|
<control />
|
||||||
<package variant="x86_64" />
|
<package variant="x86_64" />
|
||||||
<package variant="s390x">libsoup2.4-dev:s390x</package>
|
<package variant="s390x">libcurl4-gnutls-dev:s390x</package>
|
||||||
<package variant="i386" />
|
<package variant="i386" />
|
||||||
</distro>
|
</distro>
|
||||||
<distro id="ubuntu">
|
<distro id="ubuntu">
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
%global glib2_version 2.45.8
|
%global glib2_version 2.45.8
|
||||||
%global libxmlb_version 0.1.3
|
%global libxmlb_version 0.1.3
|
||||||
%global libgusb_version 0.3.5
|
%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 libjcat_version 0.1.0
|
||||||
%global systemd_version 231
|
%global systemd_version 231
|
||||||
%global json_glib_version 1.1.1
|
%global json_glib_version 1.1.1
|
||||||
@ -55,7 +55,7 @@ BuildRequires: libxmlb-devel >= %{libxmlb_version}
|
|||||||
BuildRequires: libgcab1-devel
|
BuildRequires: libgcab1-devel
|
||||||
BuildRequires: libgudev1-devel
|
BuildRequires: libgudev1-devel
|
||||||
BuildRequires: libgusb-devel >= %{libgusb_version}
|
BuildRequires: libgusb-devel >= %{libgusb_version}
|
||||||
BuildRequires: libsoup-devel >= %{libsoup_version}
|
BuildRequires: libcurl-devel >= %{libcurl_version}
|
||||||
BuildRequires: libjcat-devel >= %{libjcat_version}
|
BuildRequires: libjcat-devel >= %{libjcat_version}
|
||||||
BuildRequires: polkit-devel >= 0.103
|
BuildRequires: polkit-devel >= 0.103
|
||||||
BuildRequires: sqlite-devel
|
BuildRequires: sqlite-devel
|
||||||
@ -112,7 +112,6 @@ Requires(postun): systemd
|
|||||||
Requires: glib2%{?_isa} >= %{glib2_version}
|
Requires: glib2%{?_isa} >= %{glib2_version}
|
||||||
Requires: libxmlb%{?_isa} >= %{libxmlb_version}
|
Requires: libxmlb%{?_isa} >= %{libxmlb_version}
|
||||||
Requires: libgusb%{?_isa} >= %{libgusb_version}
|
Requires: libgusb%{?_isa} >= %{libgusb_version}
|
||||||
Requires: libsoup%{?_isa} >= %{libsoup_version}
|
|
||||||
Requires: bubblewrap
|
Requires: bubblewrap
|
||||||
Requires: shared-mime-info
|
Requires: shared-mime-info
|
||||||
|
|
||||||
|
@ -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/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/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/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/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/libtasn1-6.dll"
|
||||||
File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libusb-1.0.dll"
|
File "/usr/x86_64-w64-mingw32/sys-root/mingw/bin/libusb-1.0.dll"
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <libsoup/soup.h>
|
#include <curl/curl.h>
|
||||||
#ifdef HAVE_GIO_UNIX
|
#ifdef HAVE_GIO_UNIX
|
||||||
#include <gio/gunixfdlist.h>
|
#include <gio/gunixfdlist.h>
|
||||||
#endif
|
#endif
|
||||||
@ -52,10 +52,14 @@ typedef struct {
|
|||||||
gchar *host_security_id;
|
gchar *host_security_id;
|
||||||
GDBusConnection *conn;
|
GDBusConnection *conn;
|
||||||
GDBusProxy *proxy;
|
GDBusProxy *proxy;
|
||||||
SoupSession *soup_session;
|
|
||||||
gchar *user_agent;
|
gchar *user_agent;
|
||||||
} FwupdClientPrivate;
|
} FwupdClientPrivate;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
CURL *curl;
|
||||||
|
curl_mime *mime;
|
||||||
|
} FwupdCurlHelper;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SIGNAL_CHANGED,
|
SIGNAL_CHANGED,
|
||||||
SIGNAL_STATUS_CHANGED,
|
SIGNAL_STATUS_CHANGED,
|
||||||
@ -71,7 +75,7 @@ enum {
|
|||||||
PROP_PERCENTAGE,
|
PROP_PERCENTAGE,
|
||||||
PROP_DAEMON_VERSION,
|
PROP_DAEMON_VERSION,
|
||||||
PROP_TAINTED,
|
PROP_TAINTED,
|
||||||
PROP_SOUP_SESSION,
|
PROP_SOUP_SESSION, /* unused ABI */
|
||||||
PROP_HOST_PRODUCT,
|
PROP_HOST_PRODUCT,
|
||||||
PROP_HOST_MACHINE_ID,
|
PROP_HOST_MACHINE_ID,
|
||||||
PROP_HOST_SECURITY_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)
|
G_DEFINE_TYPE_WITH_PRIVATE (FwupdClient, fwupd_client, G_TYPE_OBJECT)
|
||||||
#define GET_PRIVATE(o) (fwupd_client_get_instance_private (o))
|
#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
|
static void
|
||||||
fwupd_client_set_host_product (FwupdClient *self, const gchar *host_product)
|
fwupd_client_set_host_product (FwupdClient *self, const gchar *host_product)
|
||||||
{
|
{
|
||||||
@ -262,12 +280,6 @@ gboolean
|
|||||||
fwupd_client_ensure_networking (FwupdClient *self, GError **error)
|
fwupd_client_ensure_networking (FwupdClient *self, GError **error)
|
||||||
{
|
{
|
||||||
FwupdClientPrivate *priv = GET_PRIVATE (self);
|
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 */
|
/* check the user agent is sane */
|
||||||
if (priv->user_agent == NULL) {
|
if (priv->user_agent == NULL) {
|
||||||
@ -284,22 +296,62 @@ fwupd_client_ensure_networking (FwupdClient *self, GError **error)
|
|||||||
"user agent unsuitable; fwupd version required");
|
"user agent unsuitable; fwupd version required");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* create the soup session */
|
static int
|
||||||
session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, priv->user_agent,
|
fwupd_client_progress_callback_cb (void *clientp,
|
||||||
SOUP_SESSION_TIMEOUT, 60,
|
curl_off_t dltotal,
|
||||||
NULL);
|
curl_off_t dlnow,
|
||||||
if (session == NULL) {
|
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,
|
g_set_error_literal (error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_INTERNAL,
|
FWUPD_ERROR_INTERNAL,
|
||||||
"failed to setup networking");
|
"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 */
|
/* relax the SSL checks for broken corporate proxies */
|
||||||
if (g_getenv ("DISABLE_SSL_STRICT") != NULL)
|
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 */
|
/* set the proxy */
|
||||||
http_proxy = g_getenv ("https_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");
|
http_proxy = g_getenv ("http_proxy");
|
||||||
if (http_proxy == NULL)
|
if (http_proxy == NULL)
|
||||||
http_proxy = g_getenv ("HTTP_PROXY");
|
http_proxy = g_getenv ("HTTP_PROXY");
|
||||||
if (http_proxy != NULL && strlen (http_proxy) > 0) {
|
if (http_proxy != NULL && strlen (http_proxy) > 0)
|
||||||
g_autoptr(SoupURI) proxy_uri = soup_uri_new (http_proxy);
|
curl_easy_setopt (helper->curl, CURLOPT_PROXY, 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this disables the double-compression of the firmware.xml.gz file */
|
/* this disables the double-compression of the firmware.xml.gz file */
|
||||||
soup_session_remove_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
|
curl_easy_setopt (helper->curl, CURLOPT_HTTP_CONTENT_DECODING, 0L);
|
||||||
priv->soup_session = g_steal_pointer (&session);
|
return g_steal_pointer (&helper);
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -2234,6 +2276,13 @@ fwupd_client_install_release_download_cb (GObject *source, GAsyncResult *res, gp
|
|||||||
g_steal_pointer (&task));
|
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
|
static void
|
||||||
fwupd_client_install_release_remote_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
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(FwupdRemote) remote = NULL;
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(GTask) task = G_TASK (user_data);
|
g_autoptr(GTask) task = G_TASK (user_data);
|
||||||
g_autoptr(SoupURI) uri = NULL;
|
|
||||||
FwupdClientInstallReleaseData *data = g_task_get_task_data (task);
|
FwupdClientInstallReleaseData *data = g_task_get_task_data (task);
|
||||||
GCancellable *cancellable = g_task_get_cancellable (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 */
|
/* 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 &&
|
||||||
if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL && uri == NULL) {
|
!fwupd_client_is_url (fwupd_release_get_uri (data->release))) {
|
||||||
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
|
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
|
||||||
g_autofree gchar *path = g_path_get_dirname (fn_cache);
|
g_autofree gchar *path = g_path_get_dirname (fn_cache);
|
||||||
fn = g_build_filename (path, fwupd_release_get_uri (data->release), NULL);
|
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);
|
priv->user_agent = g_string_free (str, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static size_t
|
||||||
fwupd_client_download_chunk_cb (SoupMessage *msg, SoupBuffer *chunk, gpointer user_data)
|
fwupd_client_download_write_callback_cb (char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||||
{
|
{
|
||||||
guint percentage;
|
GByteArray *buf = (GByteArray *) userdata;
|
||||||
goffset header_size;
|
gsize realsize = size * nmemb;
|
||||||
goffset body_length;
|
g_byte_array_append (buf, (const guint8 *) ptr, realsize);
|
||||||
FwupdClient *self = FWUPD_CLIENT (user_data);
|
return realsize;
|
||||||
|
|
||||||
/* 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
FwupdClient *self = FWUPD_CLIENT (source_object);
|
||||||
g_autoptr(GError) error = NULL;
|
FwupdCurlHelper *helper = g_task_get_task_data (task);
|
||||||
g_autoptr(GTask) task = G_TASK (user_data);
|
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);
|
curl_easy_setopt (helper->curl, CURLOPT_ERRORBUFFER, errbuf);
|
||||||
if (bytes == NULL) {
|
curl_easy_setopt (helper->curl, CURLOPT_WRITEFUNCTION, fwupd_client_download_write_callback_cb);
|
||||||
g_task_return_error (task, g_steal_pointer (&error));
|
curl_easy_setopt (helper->curl, CURLOPT_WRITEDATA, buf);
|
||||||
return;
|
res = curl_easy_perform (helper->curl);
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
fwupd_client_set_status (self, FWUPD_STATUS_IDLE);
|
fwupd_client_set_status (self, FWUPD_STATUS_IDLE);
|
||||||
istr = soup_session_send_finish (priv->soup_session, res, &error);
|
if (res != CURLE_OK) {
|
||||||
if (istr == NULL) {
|
glong status_code = 0;
|
||||||
g_task_return_error (task, g_steal_pointer (&error));
|
curl_easy_getinfo (helper->curl, CURLINFO_RESPONSE_CODE, &status_code);
|
||||||
return;
|
g_debug ("status-code was %ld", status_code);
|
||||||
}
|
if (status_code == 429) {
|
||||||
|
g_task_return_new_error (task,
|
||||||
/* check the input stream before reading the data */
|
FWUPD_ERROR,
|
||||||
g_object_get (msg, "status-code", &status_code, NULL);
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
g_debug ("status-code was %u", status_code);
|
"Failed to download due to server limit");
|
||||||
if (status_code == 429) {
|
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,
|
g_task_return_new_error (task,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_INVALID_FILE,
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
"Failed to download due to server limit");
|
"%s", curl_easy_strerror (res));
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* read the input stream into a GBytes, async */
|
return;
|
||||||
fwupd_input_stream_read_bytes_async (istr, cancellable,
|
}
|
||||||
fwupd_client_read_bytes_cb,
|
g_task_return_pointer (task,
|
||||||
g_steal_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);
|
FwupdClientPrivate *priv = GET_PRIVATE (self);
|
||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
g_autoptr(SoupMessage) msg = NULL;
|
|
||||||
g_autoptr(SoupURI) uri = NULL;
|
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(FwupdCurlHelper) helper = NULL;
|
||||||
|
|
||||||
g_return_if_fail (FWUPD_IS_CLIENT (self));
|
g_return_if_fail (FWUPD_IS_CLIENT (self));
|
||||||
g_return_if_fail (url != NULL);
|
g_return_if_fail (url != NULL);
|
||||||
@ -4060,31 +4070,18 @@ fwupd_client_download_bytes_async (FwupdClient *self,
|
|||||||
|
|
||||||
/* ensure networking set up */
|
/* ensure networking set up */
|
||||||
task = g_task_new (self, cancellable, callback, callback_data);
|
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));
|
g_task_return_error (task, g_steal_pointer (&error));
|
||||||
return;
|
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 */
|
/* download data */
|
||||||
g_debug ("downloading %s", url);
|
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);
|
fwupd_client_set_status (self, FWUPD_STATUS_DOWNLOADING);
|
||||||
soup_session_send_async (priv->soup_session, msg,
|
g_task_run_in_thread (task, fwupd_client_download_bytes_thread_cb);
|
||||||
cancellable,
|
|
||||||
fwupd_client_download_bytes_cb,
|
|
||||||
g_steal_pointer (&task));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4109,42 +4106,43 @@ fwupd_client_download_bytes_finish (FwupdClient *self, GAsyncResult *res, GError
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fwupd_client_upload_bytes_cb (GObject *source,
|
fwupd_client_upload_bytes_thread_cb (GTask *task,
|
||||||
GAsyncResult *res,
|
gpointer source_object,
|
||||||
gpointer user_data)
|
gpointer task_data,
|
||||||
|
GCancellable *cancellable)
|
||||||
{
|
{
|
||||||
g_autoptr(GTask) task = G_TASK (user_data);
|
FwupdClient *self = FWUPD_CLIENT (source_object);
|
||||||
FwupdClient *self = g_task_get_source_object (task);
|
FwupdCurlHelper *helper = g_task_get_task_data (task);
|
||||||
FwupdClientPrivate *priv = GET_PRIVATE (self);
|
CURLcode res;
|
||||||
GCancellable *cancellable = g_task_get_cancellable (task);
|
gchar errbuf[CURL_ERROR_SIZE] = { '\0' };
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GByteArray) buf = g_byte_array_new ();
|
||||||
g_autoptr(GInputStream) istr = NULL;
|
|
||||||
guint status_code;
|
|
||||||
SoupMessage *msg = g_task_get_task_data (task);
|
|
||||||
|
|
||||||
/* get the result */
|
curl_easy_setopt (helper->curl, CURLOPT_ERRORBUFFER, errbuf);
|
||||||
istr = soup_session_send_finish (priv->soup_session, res, &error);
|
curl_easy_setopt (helper->curl, CURLOPT_WRITEFUNCTION, fwupd_client_download_write_callback_cb);
|
||||||
if (istr == NULL) {
|
curl_easy_setopt (helper->curl, CURLOPT_WRITEDATA, buf);
|
||||||
g_task_return_error (task, g_steal_pointer (&error));
|
res = curl_easy_perform (helper->curl);
|
||||||
return;
|
fwupd_client_set_status (self, FWUPD_STATUS_IDLE);
|
||||||
}
|
if (res != CURLE_OK) {
|
||||||
|
glong status_code = 0;
|
||||||
/* check the input stream before reading the data */
|
curl_easy_getinfo (helper->curl, CURLINFO_RESPONSE_CODE, &status_code);
|
||||||
g_object_get (msg, "status-code", &status_code, NULL);
|
g_debug ("status-code was %ld", status_code);
|
||||||
g_debug ("status-code was %u", status_code);
|
if (errbuf[0] != '\0') {
|
||||||
if (!SOUP_STATUS_IS_SUCCESSFUL (status_code)) {
|
g_task_return_new_error (task,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
|
"%s", errbuf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
g_task_return_new_error (task,
|
g_task_return_new_error (task,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_INVALID_FILE,
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
"Failed to download: %s",
|
"%s", curl_easy_strerror (res));
|
||||||
soup_status_get_phrase (status_code));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
g_task_return_pointer (task,
|
||||||
/* read the input stream into a GBytes, async */
|
g_byte_array_free_to_bytes (g_steal_pointer (&buf)),
|
||||||
fwupd_input_stream_read_bytes_async (istr, cancellable,
|
(GDestroyNotify) g_bytes_unref);
|
||||||
fwupd_client_read_bytes_cb,
|
|
||||||
g_steal_pointer (&task));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4178,8 +4176,7 @@ fwupd_client_upload_bytes_async (FwupdClient *self,
|
|||||||
{
|
{
|
||||||
FwupdClientPrivate *priv = GET_PRIVATE (self);
|
FwupdClientPrivate *priv = GET_PRIVATE (self);
|
||||||
g_autoptr(GTask) task = NULL;
|
g_autoptr(GTask) task = NULL;
|
||||||
g_autoptr(SoupMessage) msg = NULL;
|
g_autoptr(FwupdCurlHelper) helper = NULL;
|
||||||
g_autoptr(SoupURI) uri = NULL;
|
|
||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
|
|
||||||
g_return_if_fail (FWUPD_IS_CLIENT (self));
|
g_return_if_fail (FWUPD_IS_CLIENT (self));
|
||||||
@ -4189,48 +4186,37 @@ fwupd_client_upload_bytes_async (FwupdClient *self,
|
|||||||
|
|
||||||
/* ensure networking set up */
|
/* ensure networking set up */
|
||||||
task = g_task_new (self, cancellable, callback, callback_data);
|
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));
|
g_task_return_error (task, g_steal_pointer (&error));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* download data */
|
|
||||||
g_debug ("downloading %s", url);
|
|
||||||
uri = soup_uri_new (url);
|
|
||||||
|
|
||||||
/* build message */
|
/* build message */
|
||||||
if ((flags & FWUPD_CLIENT_UPLOAD_FLAG_ALWAYS_MULTIPART) > 0 ||
|
if ((flags & FWUPD_CLIENT_UPLOAD_FLAG_ALWAYS_MULTIPART) > 0 ||
|
||||||
signature != NULL) {
|
signature != NULL) {
|
||||||
g_autoptr(SoupMultipart) mp = NULL;
|
curl_mimepart *part;
|
||||||
mp = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART);
|
helper->mime = curl_mime_init (helper->curl);
|
||||||
soup_multipart_append_form_string (mp, "payload", payload);
|
curl_easy_setopt (helper->curl, CURLOPT_MIMEPOST, helper->mime);
|
||||||
if (signature != NULL)
|
part = curl_mime_addpart (helper->mime);
|
||||||
soup_multipart_append_form_string (mp, "signature", signature);
|
curl_mime_data (part, payload, CURL_ZERO_TERMINATED);
|
||||||
msg = soup_form_request_new_from_multipart (url, mp);
|
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 {
|
} else {
|
||||||
msg = soup_message_new (SOUP_METHOD_POST, url);
|
curl_easy_setopt (helper->mime, CURLOPT_POST, 1L);
|
||||||
soup_message_set_request (msg, "application/json; charset=utf-8",
|
curl_easy_setopt (helper->curl, CURLOPT_POSTFIELDSIZE, strlen (payload));
|
||||||
SOUP_MEMORY_COPY, payload, 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);
|
fwupd_client_set_status (self, FWUPD_STATUS_IDLE);
|
||||||
g_debug ("uploading to %s", url);
|
g_debug ("uploading to %s", url);
|
||||||
soup_session_send_async (priv->soup_session, msg,
|
curl_easy_setopt (helper->curl, CURLOPT_URL, url);
|
||||||
cancellable,
|
g_task_set_task_data (task, g_steal_pointer (&helper), (GDestroyNotify) fwupd_client_curl_helper_free);
|
||||||
fwupd_client_upload_bytes_cb,
|
g_task_run_in_thread (task, fwupd_client_upload_bytes_thread_cb);
|
||||||
g_steal_pointer (&task));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4269,7 +4255,7 @@ fwupd_client_get_property (GObject *object, guint prop_id,
|
|||||||
g_value_set_boolean (value, priv->tainted);
|
g_value_set_boolean (value, priv->tainted);
|
||||||
break;
|
break;
|
||||||
case PROP_SOUP_SESSION:
|
case PROP_SOUP_SESSION:
|
||||||
g_value_set_object (value, priv->soup_session);
|
g_value_set_object (value, NULL);
|
||||||
break;
|
break;
|
||||||
case PROP_PERCENTAGE:
|
case PROP_PERCENTAGE:
|
||||||
g_value_set_uint (value, priv->percentage);
|
g_value_set_uint (value, priv->percentage);
|
||||||
@ -4309,9 +4295,6 @@ fwupd_client_set_property (GObject *object, guint prop_id,
|
|||||||
case PROP_PERCENTAGE:
|
case PROP_PERCENTAGE:
|
||||||
priv->percentage = g_value_get_uint (value);
|
priv->percentage = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
case PROP_SOUP_SESSION:
|
|
||||||
g_set_object (&priv->soup_session, g_value_get_object (value));
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@ -4471,12 +4454,12 @@ fwupd_client_class_init (FwupdClientClass *klass)
|
|||||||
/**
|
/**
|
||||||
* FwupdClient:soup-session:
|
* FwupdClient:soup-session:
|
||||||
*
|
*
|
||||||
* The libsoup session.
|
* The libsoup session, now unused.
|
||||||
*
|
*
|
||||||
* Since: 1.4.5
|
* Since: 1.4.5
|
||||||
*/
|
*/
|
||||||
pspec = g_param_spec_object ("soup-session", NULL, NULL, SOUP_TYPE_SESSION,
|
pspec = g_param_spec_object ("soup-session", NULL, NULL, G_TYPE_OBJECT,
|
||||||
G_PARAM_READWRITE | G_PARAM_STATIC_NAME);
|
G_PARAM_READABLE | G_PARAM_STATIC_NAME);
|
||||||
g_object_class_install_property (object_class, PROP_SOUP_SESSION, pspec);
|
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);
|
g_object_unref (priv->conn);
|
||||||
if (priv->proxy != NULL)
|
if (priv->proxy != NULL)
|
||||||
g_object_unref (priv->proxy);
|
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);
|
G_OBJECT_CLASS (fwupd_client_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <libsoup/soup.h>
|
#include <curl/curl.h>
|
||||||
#include <jcat.h>
|
#include <jcat.h>
|
||||||
|
|
||||||
#include "fwupd-deprecated.h"
|
#include "fwupd-deprecated.h"
|
||||||
@ -67,6 +67,10 @@ enum {
|
|||||||
G_DEFINE_TYPE_WITH_PRIVATE (FwupdRemote, fwupd_remote, G_TYPE_OBJECT)
|
G_DEFINE_TYPE_WITH_PRIVATE (FwupdRemote, fwupd_remote, G_TYPE_OBJECT)
|
||||||
#define GET_PRIVATE(o) (fwupd_remote_get_instance_private (o))
|
#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
|
static void
|
||||||
fwupd_remote_set_username (FwupdRemote *self, const gchar *username)
|
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);
|
priv->filename_source = g_strdup (filename_source);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SoupURI *
|
static CURLU *
|
||||||
fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error)
|
fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error)
|
||||||
{
|
{
|
||||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
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 (FWUPD_IS_REMOTE (self), NULL);
|
||||||
g_return_val_if_fail (url != NULL, 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 */
|
/* create URI, substituting if required */
|
||||||
if (priv->firmware_base_uri != NULL) {
|
if (priv->firmware_base_uri != NULL) {
|
||||||
g_autoptr(SoupURI) uri_tmp = NULL;
|
|
||||||
g_autofree gchar *basename = NULL;
|
g_autofree gchar *basename = NULL;
|
||||||
g_autofree gchar *url2 = NULL;
|
g_autofree gchar *path_new = NULL;
|
||||||
uri_tmp = soup_uri_new (url);
|
g_autoptr(curlptr) path = NULL;
|
||||||
if (uri_tmp == NULL) {
|
g_autoptr(CURLU) uri_tmp = curl_url ();
|
||||||
|
if (curl_url_set (uri_tmp, CURLUPART_URL, url, 0) != CURLUE_OK) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_INVALID_FILE,
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
"Failed to parse URI '%s'", url);
|
"Failed to parse url '%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);
|
|
||||||
return NULL;
|
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 */
|
/* use the base URI of the metadata to build the full path */
|
||||||
} else if (g_strstr_len (url, -1, "/") == NULL) {
|
} else if (g_strstr_len (url, -1, "/") == NULL) {
|
||||||
g_autofree gchar *basename = NULL;
|
g_autofree gchar *basename = NULL;
|
||||||
g_autofree gchar *path = NULL;
|
g_autofree gchar *path_new = NULL;
|
||||||
uri = soup_uri_new (priv->metadata_uri);
|
g_autoptr(curlptr) path = NULL;
|
||||||
if (uri == NULL) {
|
if (curl_url_set (uri, CURLUPART_URL, priv->metadata_uri, 0) != CURLUE_OK) {
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_INVALID_FILE,
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
"Failed to parse metadata URI '%s'", url);
|
"Failed to parse url '%s'",
|
||||||
|
priv->metadata_uri);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
basename = g_path_get_dirname (soup_uri_get_path (uri));
|
curl_url_get (uri, CURLUPART_PATH, &path, 0);
|
||||||
path = g_build_filename (basename, url, NULL);
|
basename = g_path_get_dirname (path);
|
||||||
soup_uri_set_path (uri, path);
|
path_new = g_build_filename (basename, url, NULL);
|
||||||
|
curl_url_set (uri, CURLUPART_URL, path_new, 0);
|
||||||
|
|
||||||
/* a normal URI */
|
/* a normal URI */
|
||||||
} else {
|
} else {
|
||||||
uri = soup_uri_new (url);
|
if (curl_url_set (uri, CURLUPART_URL, url, 0) != CURLUE_OK) {
|
||||||
if (uri == NULL) {
|
|
||||||
g_set_error (error,
|
g_set_error (error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_INVALID_FILE,
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
@ -214,10 +213,10 @@ fwupd_remote_build_uri (FwupdRemote *self, const gchar *url, GError **error)
|
|||||||
|
|
||||||
/* set the username and password */
|
/* set the username and password */
|
||||||
if (priv->username != NULL)
|
if (priv->username != NULL)
|
||||||
soup_uri_set_user (uri, priv->username);
|
curl_url_set (uri, CURLUPART_USER, priv->username, 0);
|
||||||
if (priv->password != NULL)
|
if (priv->password != NULL)
|
||||||
soup_uri_set_password (uri, priv->password);
|
curl_url_set (uri, CURLUPART_PASSWORD, priv->password, 0);
|
||||||
return uri;
|
return g_steal_pointer (&uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note, this has to be set before username and password */
|
/* 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)
|
fwupd_remote_set_metadata_uri (FwupdRemote *self, const gchar *metadata_uri)
|
||||||
{
|
{
|
||||||
FwupdRemotePrivate *priv = GET_PRIVATE (self);
|
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 */
|
/* save this so we can export the object as a GVariant */
|
||||||
priv->metadata_uri = g_strdup (metadata_uri);
|
priv->metadata_uri = g_strdup (metadata_uri);
|
||||||
@ -872,10 +865,12 @@ fwupd_remote_get_checksum (FwupdRemote *self)
|
|||||||
gchar *
|
gchar *
|
||||||
fwupd_remote_build_firmware_uri (FwupdRemote *self, const gchar *url, GError **error)
|
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)
|
if (uri == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return soup_uri_to_string (uri, FALSE);
|
curl_url_get (uri, CURLUPART_URL, &tmp, 0);
|
||||||
|
return g_strdup (tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,7 +32,7 @@ install_headers([
|
|||||||
|
|
||||||
libfwupd_deps = [
|
libfwupd_deps = [
|
||||||
giounix,
|
giounix,
|
||||||
soup,
|
libcurl,
|
||||||
libjcat,
|
libjcat,
|
||||||
libjsonglib,
|
libjsonglib,
|
||||||
]
|
]
|
||||||
@ -122,19 +122,18 @@ if get_option('introspection')
|
|||||||
header : 'fwupd.h',
|
header : 'fwupd.h',
|
||||||
dependencies : [
|
dependencies : [
|
||||||
giounix,
|
giounix,
|
||||||
soup,
|
libcurl,
|
||||||
],
|
],
|
||||||
includes : [
|
includes : [
|
||||||
'Gio-2.0',
|
'Gio-2.0',
|
||||||
'GObject-2.0',
|
'GObject-2.0',
|
||||||
'Soup-2.4',
|
|
||||||
],
|
],
|
||||||
install : true
|
install : true
|
||||||
)
|
)
|
||||||
|
|
||||||
gnome.generate_vapi('fwupd',
|
gnome.generate_vapi('fwupd',
|
||||||
sources : fwupd_gir[0],
|
sources : fwupd_gir[0],
|
||||||
packages : ['gio-2.0', 'libsoup-2.4'],
|
packages : ['gio-2.0'],
|
||||||
install : true,
|
install : true,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -178,7 +177,7 @@ if get_option('tests')
|
|||||||
],
|
],
|
||||||
dependencies : [
|
dependencies : [
|
||||||
gio,
|
gio,
|
||||||
soup,
|
libcurl,
|
||||||
libjsonglib,
|
libjsonglib,
|
||||||
],
|
],
|
||||||
link_with : fwupd,
|
link_with : fwupd,
|
||||||
|
@ -143,7 +143,6 @@ fwupdplugin_pkgg.generate(
|
|||||||
'json-glib-1.0',
|
'json-glib-1.0',
|
||||||
'libarchive',
|
'libarchive',
|
||||||
'libgcab-1.0',
|
'libgcab-1.0',
|
||||||
'libsoup-2.4',
|
|
||||||
'xmlb',
|
'xmlb',
|
||||||
'jcat',
|
'jcat',
|
||||||
],
|
],
|
||||||
|
@ -208,7 +208,7 @@ endif
|
|||||||
libjcat = dependency('jcat', version : '>= 0.1.0', fallback : ['libjcat', 'libjcat_dep'])
|
libjcat = dependency('jcat', version : '>= 0.1.0', fallback : ['libjcat', 'libjcat_dep'])
|
||||||
libjsonglib = dependency('json-glib-1.0', version : '>= 1.1.1')
|
libjsonglib = dependency('json-glib-1.0', version : '>= 1.1.1')
|
||||||
valgrind = dependency('valgrind', required: false)
|
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 build_daemon
|
||||||
if get_option('polkit')
|
if get_option('polkit')
|
||||||
polkit = dependency('polkit-gobject-1', version : '>= 0.103')
|
polkit = dependency('polkit-gobject-1', version : '>= 0.103')
|
||||||
@ -448,7 +448,6 @@ if build_standalone
|
|||||||
plugin_deps += giounix
|
plugin_deps += giounix
|
||||||
plugin_deps += gmodule
|
plugin_deps += gmodule
|
||||||
plugin_deps += gusb
|
plugin_deps += gusb
|
||||||
plugin_deps += soup
|
|
||||||
plugin_deps += libarchive
|
plugin_deps += libarchive
|
||||||
plugin_deps += gudev
|
plugin_deps += gudev
|
||||||
plugin_deps += libjsonglib
|
plugin_deps += libjsonglib
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <json-glib/json-glib.h>
|
#include <json-glib/json-glib.h>
|
||||||
#include <libsoup/soup.h>
|
#include <curl/curl.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "fwupd-error.h"
|
#include "fwupd-error.h"
|
||||||
@ -22,14 +22,11 @@
|
|||||||
struct _FuRedfishClient
|
struct _FuRedfishClient
|
||||||
{
|
{
|
||||||
GObject parent_instance;
|
GObject parent_instance;
|
||||||
SoupSession *session;
|
CURL *curl;
|
||||||
gchar *hostname;
|
gchar *hostname;
|
||||||
guint port;
|
guint port;
|
||||||
gchar *username;
|
|
||||||
gchar *password;
|
|
||||||
gchar *update_uri_path;
|
gchar *update_uri_path;
|
||||||
gchar *push_uri_path;
|
gchar *push_uri_path;
|
||||||
gboolean auth_created;
|
|
||||||
gboolean use_https;
|
gboolean use_https;
|
||||||
gboolean cacheck;
|
gboolean cacheck;
|
||||||
GPtrArray *devices;
|
GPtrArray *devices;
|
||||||
@ -37,62 +34,57 @@ struct _FuRedfishClient
|
|||||||
|
|
||||||
G_DEFINE_TYPE (FuRedfishClient, fu_redfish_client, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (FuRedfishClient, fu_redfish_client, G_TYPE_OBJECT)
|
||||||
|
|
||||||
static void
|
typedef gchar curlptr;
|
||||||
fu_redfish_client_set_auth (FuRedfishClient *self, SoupURI *uri,
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(curlptr, curl_free)
|
||||||
SoupMessage *msg)
|
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) &&
|
GByteArray *buf = (GByteArray *) userdata;
|
||||||
self->auth_created == FALSE) {
|
gsize realsize = size * nmemb;
|
||||||
/*
|
g_byte_array_append (buf, (const guint8 *) ptr, realsize);
|
||||||
* Some redfish implementations miss WWW-Authenticate
|
return realsize;
|
||||||
* 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GBytes *
|
static GBytes *
|
||||||
fu_redfish_client_fetch_data (FuRedfishClient *self, const gchar *uri_path, GError **error)
|
fu_redfish_client_fetch_data (FuRedfishClient *self, const gchar *uri_path, GError **error)
|
||||||
{
|
{
|
||||||
guint status_code;
|
CURLcode res;
|
||||||
g_autoptr(SoupMessage) msg = NULL;
|
g_autofree gchar *port = g_strdup_printf ("%u", self->port);
|
||||||
g_autoptr(SoupURI) uri = NULL;
|
g_autoptr(CURLU) uri = NULL;
|
||||||
|
g_autoptr(GByteArray) buf = g_byte_array_new ();
|
||||||
|
|
||||||
/* create URI */
|
/* create URI */
|
||||||
uri = soup_uri_new (NULL);
|
uri = curl_url ();
|
||||||
soup_uri_set_scheme (uri, self->use_https ? "https" : "http");
|
curl_url_set (uri, CURLU_DEFAULT_SCHEME, self->use_https ? "https" : "http", 0);
|
||||||
soup_uri_set_path (uri, uri_path);
|
curl_url_set (uri, CURLUPART_PATH, uri_path, 0);
|
||||||
soup_uri_set_host (uri, self->hostname);
|
curl_url_set (uri, CURLUPART_HOST, self->hostname, 0);
|
||||||
soup_uri_set_port (uri, self->port);
|
curl_url_set (uri, CURLUPART_PORT, port, 0);
|
||||||
msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
|
if (curl_easy_setopt (self->curl, CURLOPT_CURLU, uri) != CURLE_OK) {
|
||||||
if (msg == NULL) {
|
g_set_error_literal (error,
|
||||||
g_autofree gchar *tmp = soup_uri_to_string (uri, FALSE);
|
FWUPD_ERROR,
|
||||||
g_set_error (error,
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
FWUPD_ERROR,
|
"failed to create message for URI");
|
||||||
FWUPD_ERROR_INVALID_FILE,
|
|
||||||
"failed to create message for URI %s", tmp);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
fu_redfish_client_set_auth (self, uri, msg);
|
curl_easy_setopt (self->curl, CURLOPT_WRITEFUNCTION, fu_redfish_client_fetch_data_cb);
|
||||||
status_code = soup_session_send_message (self->session, msg);
|
curl_easy_setopt (self->curl, CURLOPT_WRITEDATA, buf);
|
||||||
if (status_code != SOUP_STATUS_OK) {
|
res = curl_easy_perform (self->curl);
|
||||||
g_autofree gchar *tmp = soup_uri_to_string (uri, FALSE);
|
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,
|
g_set_error (error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_INVALID_FILE,
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
"failed to download %s: %s",
|
"failed to download %s: %s",
|
||||||
tmp, soup_status_get_phrase (status_code));
|
uri_str, curl_easy_strerror (res));
|
||||||
return NULL;
|
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
|
static gboolean
|
||||||
@ -569,19 +561,19 @@ fu_redfish_client_set_smbios_interfaces (FuRedfishClient *self,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
G_DEFINE_AUTOPTR_CLEANUP_FUNC(curl_mime, curl_mime_free)
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
fu_redfish_client_update (FuRedfishClient *self, FuDevice *device, GBytes *blob_fw,
|
fu_redfish_client_update (FuRedfishClient *self, FuDevice *device, GBytes *blob_fw,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
CURLcode res;
|
||||||
FwupdRelease *release;
|
FwupdRelease *release;
|
||||||
|
curl_mimepart *part;
|
||||||
g_autofree gchar *filename = NULL;
|
g_autofree gchar *filename = NULL;
|
||||||
|
g_autofree gchar *port = g_strdup_printf ("%u", self->port);
|
||||||
guint status_code;
|
g_autoptr(CURLU) uri = curl_url ();
|
||||||
g_autoptr(SoupMessage) msg = NULL;
|
g_autoptr(curl_mime) mime = curl_mime_init (self->curl);
|
||||||
g_autoptr(SoupURI) uri = NULL;
|
|
||||||
g_autoptr(SoupMultipart) multipart = NULL;
|
|
||||||
g_autoptr(SoupBuffer) buffer = NULL;
|
|
||||||
g_autofree gchar *uri_str = NULL;
|
|
||||||
|
|
||||||
/* Get the update version */
|
/* Get the update version */
|
||||||
release = fwupd_device_get_release_default (FWUPD_DEVICE (device));
|
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 */
|
/* create URI */
|
||||||
uri = soup_uri_new (NULL);
|
curl_url_set (uri, CURLU_DEFAULT_SCHEME, self->use_https ? "https" : "http", 0);
|
||||||
soup_uri_set_scheme (uri, self->use_https ? "https" : "http");
|
curl_url_set (uri, CURLUPART_PATH, self->push_uri_path, 0);
|
||||||
soup_uri_set_path (uri, self->push_uri_path);
|
curl_url_set (uri, CURLUPART_HOST, self->hostname, 0);
|
||||||
soup_uri_set_host (uri, self->hostname);
|
curl_url_set (uri, CURLUPART_PORT, port, 0);
|
||||||
soup_uri_set_port (uri, self->port);
|
if (curl_easy_setopt (self->curl, CURLOPT_CURLU, uri) != CURLE_OK) {
|
||||||
uri_str = soup_uri_to_string (uri, FALSE);
|
g_set_error_literal (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
/* Create the multipart request */
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
multipart = soup_multipart_new (SOUP_FORM_MIME_TYPE_MULTIPART);
|
"failed to create message for URI");
|
||||||
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);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
fu_redfish_client_set_auth (self, uri, msg);
|
|
||||||
status_code = soup_session_send_message (self->session, msg);
|
/* Create the multipart request */
|
||||||
if (status_code != SOUP_STATUS_OK) {
|
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,
|
g_set_error (error,
|
||||||
FWUPD_ERROR,
|
FWUPD_ERROR,
|
||||||
FWUPD_ERROR_INVALID_FILE,
|
FWUPD_ERROR_INVALID_FILE,
|
||||||
"failed to upload %s to %s: %s",
|
"failed to upload %s to %s: %s",
|
||||||
filename, uri_str,
|
filename, uri_str,
|
||||||
soup_status_get_phrase (status_code));
|
curl_easy_strerror (res));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -662,24 +651,12 @@ fu_redfish_client_setup (FuRedfishClient *self, GBytes *smbios_table, GError **e
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the soup session */
|
/* setup networking */
|
||||||
user_agent = g_strdup_printf ("%s/%s", PACKAGE_NAME, PACKAGE_VERSION);
|
user_agent = g_strdup_printf ("%s/%s", PACKAGE_NAME, PACKAGE_VERSION);
|
||||||
self->session = soup_session_new_with_options (SOUP_SESSION_USER_AGENT, user_agent,
|
curl_easy_setopt (self->curl, CURLOPT_USERAGENT , user_agent);
|
||||||
SOUP_SESSION_TIMEOUT, 60,
|
curl_easy_setopt (self->curl, CURLOPT_CONNECTTIMEOUT, 60L);
|
||||||
NULL);
|
if (self->cacheck == FALSE)
|
||||||
if (self->session == NULL) {
|
curl_easy_setopt (self->curl, CURLOPT_SSL_VERIFYPEER , 0L);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* this is optional */
|
/* this is optional */
|
||||||
if (smbios_table != NULL) {
|
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);
|
g_debug ("Hostname: %s", self->hostname);
|
||||||
if (self->port != 0)
|
if (self->port != 0)
|
||||||
g_debug ("Port: %u", self->port);
|
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 */
|
/* try to connect */
|
||||||
blob = fu_redfish_client_fetch_data (self, "/redfish/v1/", error);
|
blob = fu_redfish_client_fetch_data (self, "/redfish/v1/", error);
|
||||||
@ -800,28 +773,24 @@ fu_redfish_client_set_cacheck (FuRedfishClient *self, gboolean cacheck)
|
|||||||
void
|
void
|
||||||
fu_redfish_client_set_username (FuRedfishClient *self, const gchar *username)
|
fu_redfish_client_set_username (FuRedfishClient *self, const gchar *username)
|
||||||
{
|
{
|
||||||
g_free (self->username);
|
curl_easy_setopt (self->curl, CURLOPT_USERNAME, username);
|
||||||
self->username = g_strdup (username);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fu_redfish_client_set_password (FuRedfishClient *self, const gchar *password)
|
fu_redfish_client_set_password (FuRedfishClient *self, const gchar *password)
|
||||||
{
|
{
|
||||||
g_free (self->password);
|
curl_easy_setopt (self->curl, CURLOPT_PASSWORD, password);
|
||||||
self->password = g_strdup (password);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fu_redfish_client_finalize (GObject *object)
|
fu_redfish_client_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
FuRedfishClient *self = FU_REDFISH_CLIENT (object);
|
FuRedfishClient *self = FU_REDFISH_CLIENT (object);
|
||||||
if (self->session != NULL)
|
if (self->curl != NULL)
|
||||||
g_object_unref (self->session);
|
curl_easy_cleanup (self->curl);
|
||||||
g_free (self->update_uri_path);
|
g_free (self->update_uri_path);
|
||||||
g_free (self->push_uri_path);
|
g_free (self->push_uri_path);
|
||||||
g_free (self->hostname);
|
g_free (self->hostname);
|
||||||
g_free (self->username);
|
|
||||||
g_free (self->password);
|
|
||||||
g_ptr_array_unref (self->devices);
|
g_ptr_array_unref (self->devices);
|
||||||
G_OBJECT_CLASS (fu_redfish_client_parent_class)->finalize (object);
|
G_OBJECT_CLASS (fu_redfish_client_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
@ -837,6 +806,11 @@ static void
|
|||||||
fu_redfish_client_init (FuRedfishClient *self)
|
fu_redfish_client_init (FuRedfishClient *self)
|
||||||
{
|
{
|
||||||
self->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
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 *
|
FuRedfishClient *
|
||||||
|
@ -21,6 +21,7 @@ shared_module('fu_plugin_redfish',
|
|||||||
c_args : cargs,
|
c_args : cargs,
|
||||||
dependencies : [
|
dependencies : [
|
||||||
plugin_deps,
|
plugin_deps,
|
||||||
|
libcurl,
|
||||||
libjsonglib,
|
libjsonglib,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@ -45,6 +46,7 @@ if get_option('tests')
|
|||||||
],
|
],
|
||||||
dependencies : [
|
dependencies : [
|
||||||
plugin_deps,
|
plugin_deps,
|
||||||
|
libcurl,
|
||||||
libjsonglib,
|
libjsonglib,
|
||||||
],
|
],
|
||||||
link_with : [
|
link_with : [
|
||||||
|
@ -35,6 +35,8 @@ apps:
|
|||||||
command: fwupdagent.wrapper
|
command: fwupdagent.wrapper
|
||||||
|
|
||||||
parts:
|
parts:
|
||||||
|
curl:
|
||||||
|
source: https://curl.se/download/curl-7.73.0.tar.bz2
|
||||||
tpm2-tss:
|
tpm2-tss:
|
||||||
plugin: autotools
|
plugin: autotools
|
||||||
source: https://github.com/tpm2-software/tpm2-tss/releases/download/2.3.0/tpm2-tss-2.3.0.tar.gz
|
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
|
- libpci-dev
|
||||||
- libpolkit-gobject-1-dev
|
- libpolkit-gobject-1-dev
|
||||||
- libsmbios-dev
|
- libsmbios-dev
|
||||||
- libsoup2.4-dev
|
|
||||||
- libsqlite3-dev
|
- libsqlite3-dev
|
||||||
- libsystemd-dev
|
- libsystemd-dev
|
||||||
- locales
|
- locales
|
||||||
@ -232,7 +233,6 @@ parts:
|
|||||||
- libjson-glib-1.0-0
|
- libjson-glib-1.0-0
|
||||||
- libpolkit-gobject-1-0
|
- libpolkit-gobject-1-0
|
||||||
- libsmbios-c2
|
- libsmbios-c2
|
||||||
- libsoup2.4-1
|
|
||||||
- glib-networking
|
- glib-networking
|
||||||
- libglib2.0-bin
|
- libglib2.0-bin
|
||||||
prime:
|
prime:
|
||||||
@ -272,7 +272,7 @@ parts:
|
|||||||
- -usr/lib/*/pkgconfig
|
- -usr/lib/*/pkgconfig
|
||||||
# we don't want system gnutls leaking in
|
# we don't want system gnutls leaking in
|
||||||
- -usr/lib/*/libgnutls*
|
- -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:
|
fix-bash-completion:
|
||||||
plugin: make
|
plugin: make
|
||||||
source: contrib/snap/fix-bash-completion
|
source: contrib/snap/fix-bash-completion
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libsoup/soup.h>
|
|
||||||
#include <jcat.h>
|
#include <jcat.h>
|
||||||
|
|
||||||
#include "fu-device-private.h"
|
#include "fu-device-private.h"
|
||||||
@ -912,13 +911,11 @@ static gchar *
|
|||||||
fu_util_download_if_required (FuUtilPrivate *priv, const gchar *perhapsfn, GError **error)
|
fu_util_download_if_required (FuUtilPrivate *priv, const gchar *perhapsfn, GError **error)
|
||||||
{
|
{
|
||||||
g_autofree gchar *filename = NULL;
|
g_autofree gchar *filename = NULL;
|
||||||
g_autoptr(SoupURI) uri = NULL;
|
|
||||||
|
|
||||||
/* a local file */
|
/* a local file */
|
||||||
uri = soup_uri_new (perhapsfn);
|
|
||||||
if (g_file_test (perhapsfn, G_FILE_TEST_EXISTS))
|
if (g_file_test (perhapsfn, G_FILE_TEST_EXISTS))
|
||||||
return g_strdup (perhapsfn);
|
return g_strdup (perhapsfn);
|
||||||
if (uri == NULL)
|
if (!fu_util_is_url (perhapsfn))
|
||||||
return g_strdup (perhapsfn);
|
return g_strdup (perhapsfn);
|
||||||
|
|
||||||
/* download the firmware to a cachedir */
|
/* 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 *remote_id;
|
||||||
const gchar *uri_tmp;
|
const gchar *uri_tmp;
|
||||||
g_auto(GStrv) argv = NULL;
|
g_auto(GStrv) argv = NULL;
|
||||||
g_autoptr(SoupURI) uri = NULL;
|
|
||||||
|
|
||||||
uri_tmp = fwupd_release_get_uri (rel);
|
uri_tmp = fwupd_release_get_uri (rel);
|
||||||
if (uri_tmp == NULL) {
|
if (uri_tmp == NULL) {
|
||||||
@ -1107,8 +1103,8 @@ fu_util_install_release (FuUtilPrivate *priv, FwupdRelease *rel, GError **error)
|
|||||||
|
|
||||||
argv = g_new0 (gchar *, 2);
|
argv = g_new0 (gchar *, 2);
|
||||||
/* local remotes may have the firmware already */
|
/* local remotes may have the firmware already */
|
||||||
uri = soup_uri_new (uri_tmp);
|
if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL &&
|
||||||
if (fwupd_remote_get_kind (remote) == FWUPD_REMOTE_KIND_LOCAL && uri == NULL) {
|
!fu_util_is_url (uri_tmp)) {
|
||||||
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
|
const gchar *fn_cache = fwupd_remote_get_filename_cache (remote);
|
||||||
g_autofree gchar *path = g_path_get_dirname (fn_cache);
|
g_autofree gchar *path = g_path_get_dirname (fn_cache);
|
||||||
argv[0] = g_build_filename (path, uri_tmp, NULL);
|
argv[0] = g_build_filename (path, uri_tmp, NULL);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <gusb.h>
|
#include <gusb.h>
|
||||||
#include <xmlb.h>
|
#include <xmlb.h>
|
||||||
#include <fwupd.h>
|
#include <fwupd.h>
|
||||||
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#include "fu-common.h"
|
#include "fu-common.h"
|
||||||
#include "fu-device-private.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."));
|
g_printerr ("%s %s\n", fmt, _("This package has not been validated, it may not work properly."));
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <fwupd.h>
|
#include <fwupd.h>
|
||||||
#include <libsoup/soup.h>
|
|
||||||
|
|
||||||
/* this is only valid for tools */
|
/* this is only valid for tools */
|
||||||
#define FWUPD_ERROR_INVALID_ARGS (FWUPD_ERROR_LAST+1)
|
#define FWUPD_ERROR_INVALID_ARGS (FWUPD_ERROR_LAST+1)
|
||||||
@ -119,3 +118,4 @@ gboolean fu_util_switch_branch_warning (FwupdDevice *dev,
|
|||||||
gboolean assume_yes,
|
gboolean assume_yes,
|
||||||
GError **error);
|
GError **error);
|
||||||
void fu_util_show_unsupported_warn (void);
|
void fu_util_show_unsupported_warn (void);
|
||||||
|
gboolean fu_util_is_url (const gchar *perhaps_url);
|
||||||
|
@ -584,13 +584,11 @@ fu_util_download_if_required (FuUtilPrivate *priv, const gchar *perhapsfn, GErro
|
|||||||
{
|
{
|
||||||
g_autofree gchar *filename = NULL;
|
g_autofree gchar *filename = NULL;
|
||||||
g_autoptr(GBytes) blob = NULL;
|
g_autoptr(GBytes) blob = NULL;
|
||||||
g_autoptr(SoupURI) uri = NULL;
|
|
||||||
|
|
||||||
/* a local file */
|
/* a local file */
|
||||||
if (g_file_test (perhapsfn, G_FILE_TEST_EXISTS))
|
if (g_file_test (perhapsfn, G_FILE_TEST_EXISTS))
|
||||||
return g_strdup (perhapsfn);
|
return g_strdup (perhapsfn);
|
||||||
uri = soup_uri_new (perhapsfn);
|
if (!fu_util_is_url (perhapsfn))
|
||||||
if (uri == NULL)
|
|
||||||
return g_strdup (perhapsfn);
|
return g_strdup (perhapsfn);
|
||||||
|
|
||||||
/* download the firmware to a cachedir */
|
/* download the firmware to a cachedir */
|
||||||
|
@ -34,11 +34,11 @@ fwupdmgr = executable(
|
|||||||
fwupdplugin_incdir,
|
fwupdplugin_incdir,
|
||||||
],
|
],
|
||||||
dependencies : [
|
dependencies : [
|
||||||
|
libcurl,
|
||||||
libxmlb,
|
libxmlb,
|
||||||
giounix,
|
giounix,
|
||||||
gudev,
|
gudev,
|
||||||
gusb,
|
gusb,
|
||||||
soup,
|
|
||||||
sqlite,
|
sqlite,
|
||||||
libarchive,
|
libarchive,
|
||||||
libjsonglib,
|
libjsonglib,
|
||||||
@ -67,11 +67,11 @@ fwupdagent = executable(
|
|||||||
fwupdplugin_incdir,
|
fwupdplugin_incdir,
|
||||||
],
|
],
|
||||||
dependencies : [
|
dependencies : [
|
||||||
|
libcurl,
|
||||||
libxmlb,
|
libxmlb,
|
||||||
giounix,
|
giounix,
|
||||||
gudev,
|
gudev,
|
||||||
gusb,
|
gusb,
|
||||||
soup,
|
|
||||||
libjsonglib,
|
libjsonglib,
|
||||||
],
|
],
|
||||||
link_with : [
|
link_with : [
|
||||||
@ -102,9 +102,9 @@ fwupdoffline = executable(
|
|||||||
giounix,
|
giounix,
|
||||||
gudev,
|
gudev,
|
||||||
gusb,
|
gusb,
|
||||||
|
libcurl,
|
||||||
libjsonglib,
|
libjsonglib,
|
||||||
libxmlb,
|
libxmlb,
|
||||||
soup,
|
|
||||||
sqlite,
|
sqlite,
|
||||||
],
|
],
|
||||||
link_with : [
|
link_with : [
|
||||||
@ -153,6 +153,7 @@ fwupdtool = executable(
|
|||||||
fwupdplugin_incdir,
|
fwupdplugin_incdir,
|
||||||
],
|
],
|
||||||
dependencies : [
|
dependencies : [
|
||||||
|
libcurl,
|
||||||
libjcat,
|
libjcat,
|
||||||
libxmlb,
|
libxmlb,
|
||||||
libgcab,
|
libgcab,
|
||||||
@ -160,7 +161,6 @@ fwupdtool = executable(
|
|||||||
gmodule,
|
gmodule,
|
||||||
gudev,
|
gudev,
|
||||||
gusb,
|
gusb,
|
||||||
soup,
|
|
||||||
sqlite,
|
sqlite,
|
||||||
valgrind,
|
valgrind,
|
||||||
libarchive,
|
libarchive,
|
||||||
@ -263,7 +263,6 @@ executable(
|
|||||||
gmodule,
|
gmodule,
|
||||||
gudev,
|
gudev,
|
||||||
gusb,
|
gusb,
|
||||||
soup,
|
|
||||||
sqlite,
|
sqlite,
|
||||||
valgrind,
|
valgrind,
|
||||||
libarchive,
|
libarchive,
|
||||||
@ -323,7 +322,6 @@ if get_option('tests')
|
|||||||
gmodule,
|
gmodule,
|
||||||
gudev,
|
gudev,
|
||||||
gusb,
|
gusb,
|
||||||
soup,
|
|
||||||
sqlite,
|
sqlite,
|
||||||
valgrind,
|
valgrind,
|
||||||
libarchive,
|
libarchive,
|
||||||
|
Loading…
Reference in New Issue
Block a user