[ostree/wip/metalinks] WIP: metalink code
- From: Colin Walters <walters src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree/wip/metalinks] WIP: metalink code
- Date: Sat, 2 Aug 2014 14:49:50 +0000 (UTC)
commit 864c95078728bcdde5f2bb65fcaa05331803c2f5
Author: Colin Walters <walters verbum org>
Date: Thu Jul 31 18:50:19 2014 -0400
WIP: metalink code
Makefile-libostree.am | 2 +
src/libostree/ostree-metalink.c | 299 +++++++++++++++++++++++++++++++++++++++
src/libostree/ostree-metalink.h | 62 ++++++++
3 files changed, 363 insertions(+), 0 deletions(-)
---
diff --git a/Makefile-libostree.am b/Makefile-libostree.am
index 1b75600..e7b141a 100644
--- a/Makefile-libostree.am
+++ b/Makefile-libostree.am
@@ -112,6 +112,8 @@ if USE_LIBSOUP
libostree_1_la_SOURCES += \
src/libostree/ostree-fetcher.h \
src/libostree/ostree-fetcher.c \
+ src/libostree/ostree-metalink.h \
+ src/libostree/ostree-metalink.c \
src/libostree/ostree-repo-pull.c \
$(NULL)
libostree_1_la_CFLAGS += $(OT_INTERNAL_SOUP_CFLAGS)
diff --git a/src/libostree/ostree-metalink.c b/src/libostree/ostree-metalink.c
new file mode 100644
index 0000000..7a7e4b7
--- /dev/null
+++ b/src/libostree/ostree-metalink.c
@@ -0,0 +1,299 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2014 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "ostree-metalink.h"
+
+#include "otutil.h"
+#include "libgsystem.h"
+
+typedef enum {
+ OSTREE_METALINK_STATE_INITIAL,
+ OSTREE_METALINK_STATE_METALINK,
+ OSTREE_METALINK_STATE_FILES,
+ OSTREE_METALINK_STATE_FILE,
+ OSTREE_METALINK_STATE_SIZE,
+ OSTREE_METALINK_STATE_VERIFICATION,
+ OSTREE_METALINK_STATE_HASH,
+ OSTREE_METALINK_STATE_RESOURCES,
+ OSTREE_METALINK_STATE_URL,
+
+ OSTREE_METALINK_STATE_PASSTHROUGH, /* Ignoring unknown elements */
+ OSTREE_METALINK_STATE_ERROR
+} OstreeMetalinkState;
+
+struct OstreeMetalink
+{
+ GObject parent_instance;
+
+ OstreeMetalink *fetcher;
+
+ guint passthrough_depth;
+ OstreeMetalinkState passthrough_previous;
+
+ char *file_name;
+ guint64 size;
+ guint verification_known :1;
+ GChecksumType verification_type;
+ char *verification_value;
+
+ GPtrArray *urls;
+
+ OstreeMetalinkState state;
+};
+
+G_DEFINE_TYPE (OstreeMetalink, _ostree_metalink, G_TYPE_OBJECT)
+
+static void
+state_transition (OstreeMetalink *self,
+ OstreeMetalinkState new_state)
+{
+ g_assert (self->state != new_state);
+ self->state = new_state;
+}
+
+static void
+unknown_element (OstreeMetalink *self,
+ const char *element_name,
+ GError **error)
+{
+ state_transition (self, OSTREE_METALINK_STATE_PASSTHROUGH);
+ g_assert (self->passthrough_depth == 0);
+}
+
+static void
+metalink_parser_start (GMarkupParseContext *context,
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
+{
+ OstreeMetalink *self = user_data;
+
+ switch (self->state)
+ {
+ case OSTREE_METALINK_STATE_INITIAL:
+ if (strcmp (element_name, "metalink") == 0)
+ state_transition (self, OSTREE_METALINK_STATE_METALINK);
+ else
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_METALINK:
+ if (strcmp (element_name, "files") == 0)
+ state_transition (self, OSTREE_METALINK_STATE_FILES);
+ else
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_FILES:
+ if (strcmp (element_name, "file") == 0)
+ {
+ const char *file_name;
+
+ state_transition (self, OSTREE_METALINK_STATE_FILE);
+
+ g_clear_pointer (&self->file_name, g_free);
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING,
+ "name",
+ &file_name,
+ G_MARKUP_COLLECT_INVALID))
+ goto out;
+
+ self->file_name = g_strdup (file_name);
+ }
+ else
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_FILE:
+ if (strcmp (element_name, "size") == 0)
+ state_transition (self, OSTREE_METALINK_STATE_SIZE);
+ else if (strcmp (element_name, "verification") == 0)
+ state_transition (self, OSTREE_METALINK_STATE_VERIFICATION);
+ else if (strcmp (element_name, "resources") == 0)
+ state_transition (self, OSTREE_METALINK_STATE_RESOURCES);
+ else
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_SIZE:
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_VERIFICATION:
+ if (strcmp (element_name, "hash") == 0)
+ {
+ gs_free char *verification_type_str = NULL;
+
+ state_transition (self, OSTREE_METALINK_STATE_HASH);
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING,
+ "name",
+ &verification_type_str,
+ G_MARKUP_COLLECT_INVALID))
+ goto out;
+
+ /* Only accept sha256/sha512 */
+ self->verification_known = TRUE;
+ if (strcmp (verification_type_str, "sha256") == 0)
+ self->verification_type = G_CHECKSUM_SHA256;
+ else if (strcmp (verification_type_str, "sha512") == 0)
+ self->verification_type = G_CHECKSUM_SHA512;
+ else
+ self->verification_known = FALSE;
+ }
+ else
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_HASH:
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_RESOURCES:
+ if (strcmp (element_name, "url") == 0)
+ {
+ const char *protocol;
+
+ if (!g_markup_collect_attributes (element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ G_MARKUP_COLLECT_STRING,
+ "protocol",
+ &protocol,
+ G_MARKUP_COLLECT_INVALID))
+ goto out;
+
+ /* Ignore non-HTTP resources */
+ if (!(strcmp (protocol, "http") == 0 || strcmp (protocol, "https") == 0))
+ state_transition (self, OSTREE_METALINK_STATE_PASSTHROUGH);
+ else
+ state_transition (self, OSTREE_METALINK_STATE_URL);
+ }
+ else
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_URL:
+ unknown_element (self, element_name, error);
+ break;
+ case OSTREE_METALINK_STATE_PASSTHROUGH:
+ self->passthrough_depth++;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ out:
+ return;
+}
+
+static void
+metalink_parser_end (GMarkupParseContext *context,
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
+{
+ OstreeMetalink *self = user_data;
+}
+
+static void
+metalink_parser_text (GMarkupParseContext *context,
+ const gchar *text,
+ gsize text_len,
+ gpointer user_data,
+ GError **error)
+{
+ OstreeMetalink *self = user_data;
+
+ switch (self->state)
+ {
+ case OSTREE_METALINK_STATE_INITIAL:
+ break;
+ case OSTREE_METALINK_STATE_METALINK:
+ break;
+ case OSTREE_METALINK_STATE_FILES:
+ break;
+ case OSTREE_METALINK_STATE_FILE:
+ break;
+ case OSTREE_METALINK_STATE_SIZE:
+ {
+ gs_free char *duped = g_strndup (text, text_len);
+ self->size = g_ascii_strtoull (duped, NULL, 10);
+ }
+ break;
+ case OSTREE_METALINK_STATE_VERIFICATION:
+ break;
+ case OSTREE_METALINK_STATE_HASH:
+ {
+ g_clear_pointer (&self->verification_value, g_free);
+ self->verification_value = g_strndup (text, text_len);
+ }
+ break;
+ case OSTREE_METALINK_STATE_RESOURCES:
+ break;
+ case OSTREE_METALINK_STATE_URL:
+ break;
+ case OSTREE_METALINK_STATE_PASSTHROUGH:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ out:
+ return;
+}
+
+static void
+_ostree_metalink_finalize (GObject *object)
+{
+ OstreeMetalink *self;
+
+ self = OSTREE_METALINK (object);
+
+ G_OBJECT_CLASS (_ostree_metalink_parent_class)->finalize (object);
+}
+
+static void
+_ostree_metalink_class_init (OstreeMetalinkClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = _ostree_metalink_finalize;
+}
+
+static void
+_ostree_metalink_init (OstreeMetalink *self)
+{
+ self->urls = g_ptr_array_new_with_free_func (g_free);
+}
+
+OstreeMetalink *
+_ostree_metalink_new (OstreeFetcher *fetcher,
+ const char *requested_file,
+ guint64 max_size,
+ SoupURI *uri)
+{
+ OstreeMetalink *self = (OstreeMetalink*)g_object_new (OSTREE_TYPE_METALINK, NULL);
+
+ return self;
+}
diff --git a/src/libostree/ostree-metalink.h b/src/libostree/ostree-metalink.h
new file mode 100644
index 0000000..bb81292
--- /dev/null
+++ b/src/libostree/ostree-metalink.h
@@ -0,0 +1,62 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2014 Colin Walters <walters verbum org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#pragma once
+
+#ifndef __GI_SCANNER__
+
+#include "ostree-fetcher.h"
+
+G_BEGIN_DECLS
+
+#define OSTREE_TYPE_METALINK (_ostree_metalink_get_type ())
+#define OSTREE_METALINK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), OSTREE_TYPE_METALINK, OstreeMetalink))
+#define OSTREE_METALINK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), OSTREE_TYPE_METALINK,
OstreeMetalinkClass))
+#define OSTREE_IS_METALINK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), OSTREE_TYPE_METALINK))
+#define OSTREE_IS_METALINK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), OSTREE_TYPE_METALINK))
+#define OSTREE_METALINK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), OSTREE_TYPE_METALINK,
OstreeMetalinkClass))
+
+typedef struct OstreeMetalinkClass OstreeMetalinkClass;
+typedef struct OstreeMetalink OstreeMetalink;
+
+struct OstreeMetalinkClass
+{
+ GObjectClass parent_class;
+};
+
+GType _ostree_metalink_get_type (void) G_GNUC_CONST;
+
+OstreeMetalink *_ostree_metalink_new (OstreeFetcher *fetcher,
+ const char *requested_file,
+ guint64 max_size,
+ SoupURI *uri);
+
+void _ostree_metalink_request_async (OstreeMetalink *self,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+
+GFile *_ostree_metalink_request_finish (OstreeMetalink *self,
+ GAsyncResult *result,
+ GError **error);
+
+G_END_DECLS
+
+#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]