From 5d327081b489bd58e5fbafc5cff9c893b46e996c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
Date: Mon, 25 Mar 2019 11:44:29 +0100
Subject: [PATCH] tree: Also check fore "treeinfo" in addition to ".treeinfo"
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Akamai CDN hosted files can't start with a dot, making trees published to
a CDN having their ".treeinfo" files renamed to "treeinfo".

https://gitlab.com/libosinfo/libosinfo/issues/18

Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Cole Robinson <crobinso@redhat.com>
(cherry picked from commit e8e0ca9024847aca9d079ffb34a2bbd0494fe978)
---
 osinfo/osinfo_tree.c | 67 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 50 insertions(+), 17 deletions(-)

diff --git a/osinfo/osinfo_tree.c b/osinfo/osinfo_tree.c
index ef82807..eaac54f 100644
--- a/osinfo/osinfo_tree.c
+++ b/osinfo/osinfo_tree.c
@@ -35,6 +35,7 @@ typedef struct _CreateFromLocationAsyncData CreateFromLocationAsyncData;
 struct _CreateFromLocationAsyncData {
     GFile *file;
     gchar *location;
+    gchar *treeinfo;
 
     GTask *res;
 
@@ -594,6 +595,11 @@ static OsinfoTree *load_keyinfo(const gchar *location,
     return tree;
 }
 
+static void
+osinfo_tree_create_from_location_async_helper(const gchar *url,
+                                              const gchar *treeinfo,
+                                              GCancellable *cancellable,
+                                              CreateFromLocationAsyncData *data);
 
 static void on_location_read(GObject *source,
                              GAsyncResult *res,
@@ -613,7 +619,17 @@ static void on_location_read(GObject *source,
                                      &length,
                                      NULL,
                                      &error)) {
-        g_prefix_error(&error, _("Failed to load .treeinfo file: "));
+        /* It means no ".treeinfo" file has been found. Try again, this time
+         * looking for a "treeinfo" file. */
+        if (g_str_equal(data->treeinfo, ".treeinfo")) {
+            osinfo_tree_create_from_location_async_helper(data->location,
+                                                          "treeinfo",
+                                                          g_task_get_cancellable(data->res),
+                                                          data);
+            return;
+        }
+
+        g_prefix_error(&error, _("Failed to load .treeinfo|treeinfo file: "));
         g_task_return_error(data->res, error);
         create_from_location_async_data_free(data);
         return;
@@ -635,6 +651,35 @@ static void on_location_read(GObject *source,
     g_free(content);
 }
 
+static void
+osinfo_tree_create_from_location_async_helper(const gchar *url,
+                                              const gchar *treeinfo,
+                                              GCancellable *cancellable,
+                                              CreateFromLocationAsyncData *data)
+{
+    gchar *location;
+
+    g_return_if_fail(url != NULL);
+    g_return_if_fail(treeinfo != NULL);
+
+    location = g_strdup_printf("%s/%s", url, treeinfo);
+
+    g_clear_object(&data->file);
+    data->file = g_file_new_for_uri(location);
+
+    g_free(data->location);
+    data->location = g_strdup(url);
+
+    g_free(data->treeinfo);
+    data->treeinfo = g_strdup(treeinfo);
+
+    g_file_load_contents_async(data->file,
+                               cancellable,
+                               on_location_read,
+                               data);
+    g_free(location);
+}
+
 /**
  * osinfo_tree_create_from_location_async:
  * @location: the location of an installation tree
@@ -652,11 +697,6 @@ void osinfo_tree_create_from_location_async(const gchar *location,
                                             gpointer user_data)
 {
     CreateFromLocationAsyncData *data;
-    gchar *treeinfo;
-
-    g_return_if_fail(location != NULL);
-
-    treeinfo = g_strdup_printf("%s/.treeinfo", location);
 
     data = g_slice_new0(CreateFromLocationAsyncData);
     data->res = g_task_new(NULL,
@@ -665,17 +705,10 @@ void osinfo_tree_create_from_location_async(const gchar *location,
                            user_data);
     g_task_set_priority(data->res, priority);
 
-    data->file = g_file_new_for_uri(treeinfo);
-    data->location = g_strdup(location);
-
-    /* XXX priority ? */
-    /* XXX probe other things besides just tree info */
-    g_file_load_contents_async(data->file,
-                               cancellable,
-                               on_location_read,
-                               data);
-
-    g_free(treeinfo);
+    osinfo_tree_create_from_location_async_helper(location,
+                                                  ".treeinfo",
+                                                  cancellable,
+                                                  data);
 }
 
 
-- 
2.21.0

