summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColin Walters <walters@verbum.org>2014-08-15 15:19:08 -0400
committerColin Walters <walters@verbum.org>2014-08-15 15:19:08 -0400
commit37e089b8135ce0a85551dd13b41f3291bfaeee12 (patch)
tree3733f7dcca9bbd01105254fe92710221a25312a9
parent3750312cbcb63821cee3087841f9854f2ee2f719 (diff)
downloadostree-37e089b8135ce0a85551dd13b41f3291bfaeee12.tar.gz
wip
-rw-r--r--src/libostree/ostree-metalink.c157
-rw-r--r--src/libostree/ostree-metalink.h15
-rw-r--r--src/libostree/ostree-repo-pull.c29
3 files changed, 172 insertions, 29 deletions
diff --git a/src/libostree/ostree-metalink.c b/src/libostree/ostree-metalink.c
index f217461e..072c97ea 100644
--- a/src/libostree/ostree-metalink.c
+++ b/src/libostree/ostree-metalink.c
@@ -45,6 +45,15 @@ struct OstreeMetalink
GObject parent_instance;
OstreeMetalink *fetcher;
+ char *requested_file;
+ guint64 max_size;
+};
+
+G_DEFINE_TYPE (OstreeMetalink, _ostree_metalink, G_TYPE_OBJECT)
+
+struct OstreeMetalinkRequest
+{
+ OstreeMetalink *metalink;
guint passthrough_depth;
OstreeMetalinkState passthrough_previous;
@@ -58,22 +67,20 @@ struct OstreeMetalink
GPtrArray *urls;
OstreeMetalinkState state;
-};
-
-G_DEFINE_TYPE (OstreeMetalink, _ostree_metalink, G_TYPE_OBJECT)
+}
static void
-state_transition (OstreeMetalink *self,
- OstreeMetalinkState new_state)
+state_transition (OstreeMetalinkRequest *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)
+unknown_element (OstreeMetalinkRequest *self,
+ const char *element_name,
+ GError **error)
{
state_transition (self, OSTREE_METALINK_STATE_PASSTHROUGH);
g_assert (self->passthrough_depth == 0);
@@ -87,7 +94,7 @@ metalink_parser_start (GMarkupParseContext *context,
gpointer user_data,
GError **error)
{
- OstreeMetalink *self = user_data;
+ OstreeMetalinkRequest *self = user_data;
switch (self->state)
{
@@ -294,21 +301,139 @@ _ostree_metalink_new (OstreeFetcher *fetcher,
SoupURI *uri)
{
OstreeMetalink *self = (OstreeMetalink*)g_object_new (OSTREE_TYPE_METALINK, NULL);
+
+ self->requested_file = g_strdup (requested_file);
+ self->max_size = max_size;
return self;
}
+static void
+on_metalink_bytes_read (GObject *src,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *local_error = NULL;
+ GTask *task = user_data;
+ gs_unref_bytes GBytes *bytes = NULL;
+
+ bytes = g_input_stream_read_bytes_finish ((GInputStream*)src,
+ result, error);
+ if (!bytes)
+ goto out;
+
+ if (g_bytes_get_size (bytes) == 0)
+ {
+ g_
+ }
+ else
+ {
+ g_input_stream_read_bytes_async ((GInputStream*)src, 8192, G_PRIORITY_DEFAULT,
+ g_task_get_cancellable (task),
+ on_metalink_bytes_read, task);
+ }
+
+ out:
+ if (local_error)
+ g_task_return_error (task, local_error);
+}
+
+static void
+on_retrieved_metalink (GObject *src,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GError *local_error = NULL;
+ GTask *task = user_data;
+ gs_unref_object GInputStream *metalink_stream = NULL;
+
+ metalink_stream = ostree_fetcher_stream_uri_finish ((OstreeFetcher*)src, result, &local_error);
+ if (!metalink_stream)
+ goto out;
+
+ g_input_stream_read_bytes_async (metalink_stream, 8192, G_PRIORITY_DEFAULT,
+ g_task_get_cancellable (task),
+ on_metalink_bytes_read, task);
+
+ out:
+ if (local_error)
+ g_task_return_error (task, local_error);
+}
+
+static void
+ostree_metalink_request_unref (gpointer data)
+{
+ OstreeMetalinkRequest *request = data;
+ g_object_unref (request->metalink);
+ g_free (request);
+}
+
+
void
_ostree_metalink_request_async (OstreeMetalink *self,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
+ GTask *task = g_task_new (self, cancellable, callback, user_data);
+ OstreeMetalinkRequest *request = g_new0 (OstreeMetalinkRequest, 1);
+ request->metalink = g_object_ref (self);
+ g_task_set_task_data (task, request, ostree_metalink_request_unref);
+ _ostree_fetcher_stream_uri_async (self->fetcher, self->uri,
+ self->max_size, cancellable,
+ on_retrieved_metalink, task);
}
-GFile *
-_ostree_metalink_request_finish (OstreeMetalink *self,
- GAsyncResult *result,
- GError **error)
+gboolean
+ostree_metalink_request_finish (OstreeMetalink *self,
+ GAsyncResult *result,
+ SoupURI **out_target_uri,
+ GFile **out_data,
+ GError **error)
{
}
+
+struct MetalinkSyncCallState
+{
+ gboolean running;
+ gboolean success;
+ SoupURI **out_target_uri;
+ GFile **out_data;
+ GError **error;
+}
+
+static void
+on_async_result (GObject *src,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ MetalinkSyncCallState *state = user_data;
+
+ state->success = ostree_metalink_request_finish ((OstreeMetalink*)src, result,
+ state->out_target_uri, state->out_data,
+ state->error);
+ state->running = FALSE;
+}
+
+gboolean
+_ostree_metalink_request_sync (OstreeMetalink *self,
+ GCancellable *cancellable,
+ SoupURI **out_target_uri,
+ GFile **out_data,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GMainContext *sync_context = g_main_context_new ();
+ MetalinkSyncCallState state = { 0, };
+
+ _ostree_metalink_request_async (self, cancellable, on_async_result, &state);
+
+ while (state.running)
+ g_main_context_iteration (sync_context, TRUE);
+
+ ret = state.success;
+ out:
+ if (sync_context)
+ g_main_context_unref (sync_context);
+ return ret;
+}
diff --git a/src/libostree/ostree-metalink.h b/src/libostree/ostree-metalink.h
index bb81292c..72bdfb5e 100644
--- a/src/libostree/ostree-metalink.h
+++ b/src/libostree/ostree-metalink.h
@@ -48,14 +48,23 @@ OstreeMetalink *_ostree_metalink_new (OstreeFetcher *fetcher,
guint64 max_size,
SoupURI *uri);
+gboolean _ostree_metalink_request_sync (OstreeMetalink *self,
+ SoupURI **out_target_uri,
+ GFile **out_data,
+ GCancellable *cancellable,
+ GError **error);
+
+
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);
+gboolean_ostree_metalink_request_finish (OstreeMetalink *self,
+ GAsyncResult *result,
+ SoupURI **out_target_uri,
+ GFile **out_data,
+ GError **error);
G_END_DECLS
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index 9be8f324..7a0917b8 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -1034,6 +1034,7 @@ ostree_repo_pull (OstreeRepo *self,
gs_unref_hashtable GHashTable *requested_refs_to_fetch = NULL;
gs_unref_hashtable GHashTable *commits_to_fetch = NULL;
gs_free char *remote_mode_str = NULL;
+ gs_unref_object OstreeMetalink *metalink = NULL;
OtPullData pull_data_real = { 0, };
OtPullData *pull_data = &pull_data_real;
GKeyFile *config = NULL;
@@ -1072,26 +1073,34 @@ ostree_repo_pull (OstreeRepo *self,
goto out;
}
- if (!ot_keyfile_get_value_with_default (self, remote_key, "metalink", &metalink_url, error))
+ if (!repo_get_string_key_inherit (self, remote_key, "metalink", &metalink_url, error))
goto out;
if (!metalink_url)
{
if (!repo_get_string_key_inherit (self, remote_key, "url", &baseurl, error))
goto out;
+
+ pull_data->base_uri = soup_uri_new (baseurl);
+
+ if (!pull_data->base_uri)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to parse url '%s'", baseurl);
+ goto out;
+ }
}
else
{
- FIXME - need to retrieve the metalink value, extract checksum for ref from it
- }
+ gs_unref_object GFile *metalink_data = NULL;
+ SoupURI *metalink_uri = soup_uri_new (metalink_url);
+ metalink = _ostree_metalink_new (pull_data->fetcher, metalink_url, OSTREE_MAX_METADATA_SIZE, metalink_uri);
+ g_object_unref (metalink_uri);
- pull_data->base_uri = soup_uri_new (baseurl);
-
- if (!pull_data->base_uri)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to parse url '%s'", baseurl);
- goto out;
+ if (!_ostree_metalink_request_sync (metalink, &pull_data->base_uri,
+ &metalink_data,
+ cancellable, error))
+ goto out;
}
#ifdef HAVE_GPGME