[gnome-software/wip/mcrha/odrs-download-etag] gs-plugin: Add gs_plugin_download_file_full()



commit 5401fb1d4be3f3f22287a720af7442b3e80184ef
Author: Milan Crha <mcrha redhat com>
Date:   Mon Oct 18 17:41:04 2021 +0200

    gs-plugin: Add gs_plugin_download_file_full()
    
    The function uses ETag-s to avoid downloading of a file, which
    did not change on the server.

 lib/gs-plugin.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 lib/gs-plugin.h |  8 ++++++++
 2 files changed, 53 insertions(+)
---
diff --git a/lib/gs-plugin.c b/lib/gs-plugin.c
index 767bb2332..ff96c474c 100644
--- a/lib/gs-plugin.c
+++ b/lib/gs-plugin.c
@@ -1080,6 +1080,38 @@ gs_plugin_download_file (GsPlugin *plugin,
                         const gchar *filename,
                         GCancellable *cancellable,
                         GError **error)
+{
+       return gs_plugin_download_file_full (plugin, app, uri, filename, NULL, NULL, cancellable, error);
+}
+
+/**
+ * gs_plugin_download_file_full:
+ * @plugin: a #GsPlugin
+ * @app: a #GsApp, or %NULL
+ * @uri: a remote URI
+ * @filename: a local filename
+ * @last_etag: (nullable): a last etag, or %NULL
+ * @out_new_etag: (nullable) (out): where to store a new etag, or %NULL
+ * @cancellable: a #GCancellable, or %NULL
+ * @error: a #GError, or %NULL
+ *
+ * Downloads data and saves it to a file. When the file exists and the @last_etag
+ * is provided, then can avoid the download when the file did not change
+ * on the server.
+ *
+ * Returns: %TRUE for success
+ *
+ * Since: 42
+ **/
+gboolean
+gs_plugin_download_file_full (GsPlugin *plugin,
+                             GsApp *app,
+                             const gchar *uri,
+                             const gchar *filename,
+                             const gchar *last_etag,
+                             gchar **out_new_etag,
+                             GCancellable *cancellable,
+                             GError **error)
 {
        GsPluginPrivate *priv = gs_plugin_get_instance_private (plugin);
        GsPluginDownloadHelper helper;
@@ -1134,7 +1166,14 @@ gs_plugin_download_file (GsPlugin *plugin,
                                  G_CALLBACK (gs_plugin_download_chunk_cb),
                                  &helper);
        }
+       if (last_etag != NULL && *last_etag != '\0' && g_file_test (filename, G_FILE_TEST_EXISTS))
+               soup_message_headers_append (msg->request_headers, "If-None-Match", last_etag);
        status_code = soup_session_send_message (priv->soup_session, msg);
+       if (status_code == SOUP_STATUS_NOT_MODIFIED) {
+               if (out_new_etag)
+                       *out_new_etag = g_strdup (last_etag);
+               return TRUE;
+       }
        if (status_code != SOUP_STATUS_OK) {
                g_autoptr(GString) str = g_string_new (NULL);
                g_string_append (str, soup_status_get_phrase (status_code));
@@ -1162,6 +1201,12 @@ gs_plugin_download_file (GsPlugin *plugin,
                             error_local->message);
                return FALSE;
        }
+       if (out_new_etag) {
+               const gchar *new_etag;
+               new_etag = soup_message_headers_get_one (msg->response_headers, "ETag");
+               if (new_etag != NULL && *new_etag != '\0')
+                       *out_new_etag = g_strdup (new_etag);
+       }
        return TRUE;
 }
 
diff --git a/lib/gs-plugin.h b/lib/gs-plugin.h
index b4c529324..8a1cad854 100644
--- a/lib/gs-plugin.h
+++ b/lib/gs-plugin.h
@@ -88,6 +88,14 @@ gboolean      gs_plugin_download_file                (GsPlugin       *plugin,
                                                         const gchar    *filename,
                                                         GCancellable   *cancellable,
                                                         GError         **error);
+gboolean       gs_plugin_download_file_full            (GsPlugin *plugin,
+                                                        GsApp *app,
+                                                        const gchar *uri,
+                                                        const gchar *filename,
+                                                        const gchar *last_etag,
+                                                        gchar **out_new_etag,
+                                                        GCancellable *cancellable,
+                                                        GError **error);
 gchar          *gs_plugin_download_rewrite_resource    (GsPlugin       *plugin,
                                                         GsApp          *app,
                                                         const gchar    *resource,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]