25 | 25 |
#include <config.h>
|
26 | 26 |
|
27 | 27 |
#include <osinfo/osinfo.h>
|
|
28 |
#include "osinfo_util_private.h"
|
28 | 29 |
#include <gio/gio.h>
|
29 | 30 |
#include <stdlib.h>
|
30 | 31 |
#include <string.h>
|
31 | 32 |
#include <glib/gi18n-lib.h>
|
|
33 |
#include <libsoup/soup.h>
|
32 | 34 |
|
33 | 35 |
typedef struct _CreateFromLocationAsyncData CreateFromLocationAsyncData;
|
34 | 36 |
struct _CreateFromLocationAsyncData {
|
35 | |
GFile *file;
|
|
37 |
SoupSession *session;
|
|
38 |
SoupMessage *message;
|
|
39 |
|
|
40 |
gchar *content;
|
36 | 41 |
gchar *location;
|
37 | 42 |
gchar *treeinfo;
|
38 | 43 |
|
|
41 | 46 |
|
42 | 47 |
static void create_from_location_async_data_free(CreateFromLocationAsyncData *data)
|
43 | 48 |
{
|
44 | |
g_object_unref(data->file);
|
|
49 |
g_object_unref(data->session);
|
|
50 |
g_object_unref(data->message);
|
45 | 51 |
g_object_unref(data->res);
|
46 | 52 |
|
47 | 53 |
g_slice_free(CreateFromLocationAsyncData, data);
|
|
475 | 481 |
* @error: The location where to store any error, or %NULL
|
476 | 482 |
*
|
477 | 483 |
* Creates a new #OsinfoTree for installation tree at @location. The @location
|
478 | |
* could be any URI that GIO can handle or a local path.
|
|
484 |
* could be a http:// or a https:// URI.
|
479 | 485 |
*
|
480 | 486 |
* NOTE: Currently this only works for trees with a .treeinfo file
|
481 | 487 |
*
|
|
652 | 658 |
osinfo_tree_create_from_location_async_helper(CreateFromLocationAsyncData *data,
|
653 | 659 |
const gchar *treeinfo);
|
654 | 660 |
|
|
661 |
static void on_content_read(GObject *source,
|
|
662 |
GAsyncResult *res,
|
|
663 |
gpointer user_data)
|
|
664 |
{
|
|
665 |
CreateFromLocationAsyncData *data;
|
|
666 |
gsize length = 0;
|
|
667 |
GError *error = NULL;
|
|
668 |
OsinfoTree *ret;
|
|
669 |
|
|
670 |
data = (CreateFromLocationAsyncData *)user_data;
|
|
671 |
|
|
672 |
if (!g_input_stream_read_all_finish(G_INPUT_STREAM(source),
|
|
673 |
res,
|
|
674 |
&length,
|
|
675 |
&error)) {
|
|
676 |
g_prefix_error(&error, _("Failed to load .treeinfo|treeinfo content: "));
|
|
677 |
g_task_return_error(data->res, error);
|
|
678 |
create_from_location_async_data_free(data);
|
|
679 |
}
|
|
680 |
|
|
681 |
if (!(ret = load_keyinfo(data->location,
|
|
682 |
data->content,
|
|
683 |
length,
|
|
684 |
&error))) {
|
|
685 |
g_prefix_error(&error, _("Failed to process keyinfo file: "));
|
|
686 |
g_task_return_error(data->res, error);
|
|
687 |
goto cleanup;
|
|
688 |
}
|
|
689 |
|
|
690 |
g_task_return_pointer(data->res, ret, g_object_unref);
|
|
691 |
|
|
692 |
cleanup:
|
|
693 |
create_from_location_async_data_free(data);
|
|
694 |
}
|
|
695 |
|
655 | 696 |
static void on_location_read(GObject *source,
|
656 | 697 |
GAsyncResult *res,
|
657 | 698 |
gpointer user_data)
|
658 | 699 |
{
|
659 | 700 |
CreateFromLocationAsyncData *data;
|
660 | 701 |
GError *error = NULL;
|
661 | |
gchar *content = NULL;
|
662 | |
gsize length = 0;
|
663 | |
OsinfoTree *ret = NULL;
|
|
702 |
GInputStream *stream;
|
|
703 |
goffset content_size;
|
664 | 704 |
|
665 | 705 |
data = (CreateFromLocationAsyncData *)user_data;
|
666 | 706 |
|
667 | |
if (!g_file_load_contents_finish(G_FILE(source),
|
668 | |
res,
|
669 | |
&content,
|
670 | |
&length,
|
671 | |
NULL,
|
672 | |
&error)) {
|
|
707 |
stream = soup_session_send_finish(SOUP_SESSION(source),
|
|
708 |
res,
|
|
709 |
&error);
|
|
710 |
if (stream == NULL ||
|
|
711 |
!SOUP_STATUS_IS_SUCCESSFUL(data->message->status_code)) {
|
673 | 712 |
/* It means no ".treeinfo" file has been found. Try again, this time
|
674 | 713 |
* looking for a "treeinfo" file. */
|
675 | 714 |
if (g_str_equal(data->treeinfo, ".treeinfo")) {
|
|
677 | 716 |
return;
|
678 | 717 |
}
|
679 | 718 |
|
|
719 |
if (error == NULL) {
|
|
720 |
g_set_error_literal(&error,
|
|
721 |
OSINFO_TREE_ERROR,
|
|
722 |
OSINFO_TREE_ERROR_NO_TREEINFO,
|
|
723 |
soup_status_get_phrase(data->message->status_code));
|
|
724 |
}
|
680 | 725 |
g_prefix_error(&error, _("Failed to load .treeinfo|treeinfo file: "));
|
681 | 726 |
g_task_return_error(data->res, error);
|
682 | 727 |
create_from_location_async_data_free(data);
|
683 | 728 |
return;
|
684 | 729 |
}
|
685 | 730 |
|
686 | |
if (!(ret = load_keyinfo(data->location,
|
687 | |
content,
|
688 | |
length,
|
689 | |
&error))) {
|
690 | |
g_prefix_error(&error, _("Failed to process keyinfo file: "));
|
691 | |
g_task_return_error(data->res, error);
|
692 | |
goto cleanup;
|
693 | |
}
|
694 | |
|
695 | |
g_task_return_pointer(data->res, ret, g_object_unref);
|
696 | |
|
697 | |
cleanup:
|
698 | |
create_from_location_async_data_free(data);
|
699 | |
g_free(content);
|
|
731 |
content_size = soup_message_headers_get_content_length(data->message->response_headers);
|
|
732 |
data->content = g_malloc0(content_size);
|
|
733 |
|
|
734 |
g_input_stream_read_all_async(stream,
|
|
735 |
data->content,
|
|
736 |
content_size,
|
|
737 |
g_task_get_priority(data->res),
|
|
738 |
g_task_get_cancellable(data->res),
|
|
739 |
on_content_read,
|
|
740 |
data);
|
700 | 741 |
}
|
701 | 742 |
|
702 | 743 |
static void
|
|
707 | 748 |
|
708 | 749 |
g_return_if_fail(treeinfo != NULL);
|
709 | 750 |
|
|
751 |
if (!osinfo_util_requires_soup(data->location)) {
|
|
752 |
GError *error = NULL;
|
|
753 |
|
|
754 |
g_set_error_literal(&error,
|
|
755 |
OSINFO_TREE_ERROR,
|
|
756 |
OSINFO_TREE_ERROR_NOT_SUPPORTED_PROTOCOL,
|
|
757 |
_("URL protocol is not supported"));
|
|
758 |
|
|
759 |
g_task_return_error(data->res, error);
|
|
760 |
}
|
|
761 |
|
710 | 762 |
location = g_strdup_printf("%s/%s", data->location, treeinfo);
|
711 | 763 |
|
712 | |
g_clear_object(&data->file);
|
713 | |
data->file = g_file_new_for_uri(location);
|
|
764 |
if (data->session == NULL)
|
|
765 |
data->session = soup_session_new();
|
|
766 |
|
|
767 |
g_clear_object(&data->message);
|
|
768 |
data->message = soup_message_new("GET", location);
|
714 | 769 |
|
715 | 770 |
g_free(data->treeinfo);
|
716 | 771 |
data->treeinfo = g_strdup(treeinfo);
|
717 | 772 |
|
718 | |
g_file_load_contents_async(data->file,
|
719 | |
g_task_get_cancellable(data->res),
|
720 | |
on_location_read,
|
721 | |
data);
|
|
773 |
soup_session_send_async(data->session,
|
|
774 |
data->message,
|
|
775 |
g_task_get_cancellable(data->res),
|
|
776 |
on_location_read,
|
|
777 |
data);
|
722 | 778 |
g_free(location);
|
723 | 779 |
}
|
724 | 780 |
|