[tracker/wip/carlosg/remote-module-reduction: 1/6] libtracker-sparql: Add base http helper object definitions




commit fa5aaa24a844b6bbdf55fd08ff0a1fc6d5b2da75
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Apr 23 13:41:06 2022 +0200

    libtracker-sparql: Add base http helper object definitions
    
    This is a small internal API consisting of a TrackerHttpClient and
    a TrackerHttpServer abstract objects. These are meant to wrap the
    interaction with libsoup in a way that is most isolated from internal
    library workings.
    
    These objects will have final implementations living in modules, but
    also will be interacted through the base API from the library code,
    this so far adds the latter.

 src/libtracker-sparql/meson.build           |   2 +
 src/libtracker-sparql/remote/meson.build    |   3 +
 src/libtracker-sparql/remote/tracker-http.c | 334 ++++++++++++++++++++++++++++
 src/libtracker-sparql/remote/tracker-http.h | 122 ++++++++++
 4 files changed, 461 insertions(+)
---
diff --git a/src/libtracker-sparql/meson.build b/src/libtracker-sparql/meson.build
index a55fb3826..bb0aee5a5 100644
--- a/src/libtracker-sparql/meson.build
+++ b/src/libtracker-sparql/meson.build
@@ -1,6 +1,7 @@
 subdir('core')
 subdir('bus')
 subdir('direct')
+subdir('remote')
 
 version_header = configure_file(
     input: 'tracker-version-generated.h.meson.in',
@@ -93,6 +94,7 @@ libtracker_sparql_private = static_library('tracker-sparql-private',
     core_files,
     bus_files,
     direct_files,
+    remote_files,
     '../libtracker-common/libtracker-common.vapi',
     'core/libtracker-data.vapi',
     'direct/tracker-direct.vapi',
diff --git a/src/libtracker-sparql/remote/meson.build b/src/libtracker-sparql/remote/meson.build
new file mode 100644
index 000000000..5cc639795
--- /dev/null
+++ b/src/libtracker-sparql/remote/meson.build
@@ -0,0 +1,3 @@
+remote_files = files(
+    'tracker-http.c',
+)
diff --git a/src/libtracker-sparql/remote/tracker-http.c b/src/libtracker-sparql/remote/tracker-http.c
new file mode 100644
index 000000000..345f8412d
--- /dev/null
+++ b/src/libtracker-sparql/remote/tracker-http.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2022, Red Hat Inc.
+ *
+ * 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.1 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+#include <tracker-sparql.h>
+#include <dlfcn.h>
+
+#include "tracker-http.h"
+
+static GType client_type = G_TYPE_NONE;
+static GType server_type = G_TYPE_NONE;
+
+/* Module loading */
+#define LIBSOUP_2_SONAME "libsoup-2.4.so.1"
+
+static void
+ensure_types (void)
+{
+       const char *modules[3] = { 0 };
+       gpointer handle = NULL;
+       gint i = 0;
+
+       if (client_type != G_TYPE_NONE)
+               return;
+
+       g_assert (g_module_supported ());
+
+#ifdef HAVE_RTLD_NOLOAD
+       if ((handle = dlopen (LIBSOUP_2_SONAME, RTLD_NOW | RTLD_NOLOAD))) {
+               /* Force load of soup2 module */
+               modules[0] = "libtracker-http-soup2.so";
+       } else
+#endif
+       {
+               modules[0] = "libtracker-http-soup3.so";
+               modules[1] = "libtracker-http-soup2.so";
+       }
+
+       g_clear_pointer (&handle, dlclose);
+
+       for (i = 0; modules[i]; i++) {
+               GModule *remote_module;
+               gchar *module_path;
+               void (* init_func) (GType *client, GType *server);
+
+               if (g_strcmp0 (g_get_current_dir (), BUILDROOT) == 0) {
+                       /* Detect in-build runtime of this code, this may happen
+                        * building introspection information or running tests.
+                        * We want the in-tree modules to be loaded then.
+                        */
+                       module_path = g_strdup_printf (BUILD_LIBDIR "/remote/%s", modules[i]);
+               } else {
+                       module_path = g_strdup_printf (PRIVATE_LIBDIR "/%s", modules[i]);
+               }
+
+               if (!g_file_test (module_path, G_FILE_TEST_EXISTS)) {
+                       g_free (module_path);
+                       continue;
+               }
+
+               remote_module = g_module_open (module_path,
+                                              G_MODULE_BIND_LAZY |
+                                              G_MODULE_BIND_LOCAL);
+               g_free (module_path);
+
+               if (!remote_module) {
+                       g_printerr ("Could not load '%s': %s\n",
+                                   modules[i], g_module_error ());
+                       continue;
+               }
+
+               if (!g_module_symbol (remote_module, "initialize_types", (gpointer *) &init_func)) {
+                       g_printerr ("Could find init function: %s\n",
+                                   g_module_error ());
+                       g_clear_pointer (&remote_module, g_module_close);
+                       continue;
+               }
+
+               g_type_ensure (TRACKER_TYPE_HTTP_CLIENT);
+               g_type_ensure (TRACKER_TYPE_HTTP_SERVER);
+
+               init_func (&client_type, &server_type);
+
+               g_module_make_resident (remote_module);
+               g_module_close (remote_module);
+
+               g_assert (client_type != G_TYPE_NONE);
+               g_assert (server_type != G_TYPE_NONE);
+               return;
+       }
+
+       g_assert_not_reached ();
+}
+
+/* HTTP server */
+enum {
+       PROP_0,
+       PROP_HTTP_PORT,
+       PROP_HTTP_CERTIFICATE,
+       N_SERVER_PROPS
+};
+
+enum {
+       REQUEST,
+       N_SERVER_SIGNALS,
+};
+
+typedef struct
+{
+       guint port;
+       GTlsCertificate *certificate;
+} TrackerHttpServerPrivate;
+
+static GParamSpec *server_props[N_SERVER_PROPS] = { 0 };
+static guint server_signals[N_SERVER_SIGNALS] = { 0 };
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (TrackerHttpServer,
+                                     tracker_http_server,
+                                     G_TYPE_OBJECT)
+
+static void
+tracker_http_server_set_property (GObject      *object,
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+       TrackerHttpServer *server = TRACKER_HTTP_SERVER (object);
+       TrackerHttpServerPrivate *priv =
+               tracker_http_server_get_instance_private (server);
+
+       switch (prop_id) {
+       case PROP_HTTP_PORT:
+               priv->port = g_value_get_uint (value);
+               break;
+       case PROP_HTTP_CERTIFICATE:
+               priv->certificate = g_value_dup_object (value);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+       }
+}
+
+static void
+tracker_http_server_get_property (GObject    *object,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+       TrackerHttpServer *server = TRACKER_HTTP_SERVER (object);
+       TrackerHttpServerPrivate *priv =
+               tracker_http_server_get_instance_private (server);
+
+       switch (prop_id) {
+       case PROP_HTTP_PORT:
+               g_value_set_uint (value, priv->port);
+               break;
+       case PROP_HTTP_CERTIFICATE:
+               g_value_set_object (value, priv->certificate);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+       }
+}
+
+static void
+tracker_http_server_class_init (TrackerHttpServerClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       object_class->set_property = tracker_http_server_set_property;
+       object_class->get_property = tracker_http_server_get_property;
+
+       server_signals[REQUEST] =
+               g_signal_new ("request",
+                             TRACKER_TYPE_HTTP_SERVER, 0, 0,
+                             NULL, NULL, NULL,
+                             G_TYPE_NONE, 5,
+                             G_TYPE_SOCKET_ADDRESS,
+                             G_TYPE_STRING,
+                             G_TYPE_HASH_TABLE,
+                             G_TYPE_UINT,
+                             G_TYPE_POINTER);
+
+       server_props[PROP_HTTP_PORT] =
+               g_param_spec_uint ("http-port",
+                                  "HTTP Port",
+                                  "HTTP Port",
+                                  0, G_MAXUINT,
+                                  8080,
+                                  G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+       server_props[PROP_HTTP_CERTIFICATE] =
+               g_param_spec_object ("http-certificate",
+                                    "HTTP certificate",
+                                    "HTTP certificate",
+                                    G_TYPE_TLS_CERTIFICATE,
+                                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+
+       g_object_class_install_properties (object_class,
+                                          N_SERVER_PROPS,
+                                          server_props);
+}
+
+static void
+tracker_http_server_init (TrackerHttpServer *server)
+{
+}
+
+TrackerHttpServer *
+tracker_http_server_new (guint             port,
+                         GTlsCertificate  *certificate,
+                         GCancellable     *cancellable,
+                         GError          **error)
+{
+       ensure_types ();
+
+       return g_initable_new (server_type,
+                              cancellable, error,
+                              "http-port", port,
+                              "http-certificate", certificate,
+                              NULL);
+}
+
+void
+tracker_http_server_response (TrackerHttpServer       *server,
+                              TrackerHttpRequest      *request,
+                              TrackerSerializerFormat  format,
+                              GInputStream            *content)
+{
+       TRACKER_HTTP_SERVER_GET_CLASS (server)->response (server,
+                                                         request,
+                                                         format,
+                                                         content);
+}
+
+void
+tracker_http_server_error (TrackerHttpServer  *server,
+                           TrackerHttpRequest *request,
+                           gint                code,
+                           const gchar        *message)
+{
+       TRACKER_HTTP_SERVER_GET_CLASS (server)->error (server,
+                                                      request,
+                                                      code,
+                                                      message);
+}
+
+/* HTTP client */
+G_DEFINE_ABSTRACT_TYPE (TrackerHttpClient, tracker_http_client, G_TYPE_OBJECT)
+
+static void
+tracker_http_client_class_init (TrackerHttpClientClass *klass)
+{
+}
+
+static void
+tracker_http_client_init (TrackerHttpClient *server)
+{
+}
+
+TrackerHttpClient *
+tracker_http_client_new (void)
+{
+       ensure_types ();
+
+       return g_object_new (client_type, NULL);
+}
+
+void
+tracker_http_client_send_message_async (TrackerHttpClient   *client,
+                                        const gchar         *uri,
+                                        const gchar         *query,
+                                        guint                formats,
+                                        GCancellable        *cancellable,
+                                        GAsyncReadyCallback  callback,
+                                        gpointer             user_data)
+{
+       TRACKER_HTTP_CLIENT_GET_CLASS (client)->send_message_async (client,
+                                                                   uri,
+                                                                   query,
+                                                                   formats,
+                                                                   cancellable,
+                                                                   callback,
+                                                                   user_data);
+}
+
+GInputStream *
+tracker_http_client_send_message_finish (TrackerHttpClient        *client,
+                                         GAsyncResult             *res,
+                                         TrackerSerializerFormat  *format,
+                                         GError                  **error)
+{
+       return TRACKER_HTTP_CLIENT_GET_CLASS (client)->send_message_finish (client,
+                                                                           res,
+                                                                           format,
+                                                                           error);
+}
+
+GInputStream *
+tracker_http_client_send_message (TrackerHttpClient        *client,
+                                  const gchar              *uri,
+                                  const gchar              *query,
+                                  guint                     formats,
+                                  GCancellable             *cancellable,
+                                  TrackerSerializerFormat  *format,
+                                  GError                  **error)
+{
+       return TRACKER_HTTP_CLIENT_GET_CLASS (client)->send_message (client,
+                                                                    uri,
+                                                                    query,
+                                                                    formats,
+                                                                    cancellable,
+                                                                    format,
+                                                                    error);
+}
diff --git a/src/libtracker-sparql/remote/tracker-http.h b/src/libtracker-sparql/remote/tracker-http.h
new file mode 100644
index 000000000..15e3498c0
--- /dev/null
+++ b/src/libtracker-sparql/remote/tracker-http.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2022, Red Hat Inc.
+ *
+ * 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.1 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ *
+ * Author: Carlos Garnacho <carlosg gnome org>
+ */
+
+#ifndef TRACKER_HTTP_H
+#define TRACKER_HTTP_H
+
+#include <gio/gio.h>
+
+#ifndef MODULE
+#include <libtracker-sparql/tracker-enums-private.h>
+#endif
+
+typedef struct _TrackerHttpRequest TrackerHttpRequest;
+
+#define TRACKER_TYPE_HTTP_SERVER (tracker_http_server_get_type ())
+G_DECLARE_DERIVABLE_TYPE (TrackerHttpServer,
+                          tracker_http_server,
+                          TRACKER, HTTP_SERVER,
+                          GObject)
+
+struct _TrackerHttpServerClass {
+       GObjectClass parent_class;
+
+       void (* response) (TrackerHttpServer       *server,
+                          TrackerHttpRequest      *request,
+                          TrackerSerializerFormat  format,
+                          GInputStream            *content);
+       void (* error) (TrackerHttpServer  *server,
+                       TrackerHttpRequest *request,
+                       gint                code,
+                       const gchar        *message);
+};
+
+TrackerHttpServer * tracker_http_server_new (guint             port,
+                                             GTlsCertificate  *certificate,
+                                             GCancellable     *cancellable,
+                                             GError          **error);
+
+void tracker_http_server_response (TrackerHttpServer       *server,
+                                   TrackerHttpRequest      *request,
+                                   TrackerSerializerFormat  format,
+                                   GInputStream            *content);
+
+void tracker_http_server_error (TrackerHttpServer       *server,
+                                TrackerHttpRequest      *request,
+                                gint                     code,
+                                const gchar             *message);
+
+#define TRACKER_TYPE_HTTP_CLIENT (tracker_http_client_get_type ())
+G_DECLARE_DERIVABLE_TYPE (TrackerHttpClient,
+                          tracker_http_client,
+                          TRACKER, HTTP_CLIENT,
+                          GObject)
+
+struct _TrackerHttpClientClass {
+       GObjectClass parent_class;
+
+       void (* send_message_async) (TrackerHttpClient   *client,
+                                    const gchar         *uri,
+                                    const gchar         *query,
+                                    guint                formats,
+                                    GCancellable        *cancellable,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data);
+       GInputStream * (* send_message_finish) (TrackerHttpClient        *client,
+                                               GAsyncResult             *res,
+                                               TrackerSerializerFormat  *format,
+                                               GError                  **error);
+       GInputStream * (* send_message) (TrackerHttpClient        *client,
+                                        const gchar              *uri,
+                                        const gchar              *query,
+                                        guint                     formats,
+                                        GCancellable             *cancellable,
+                                        TrackerSerializerFormat  *format,
+                                        GError                  **error);
+};
+
+TrackerHttpClient * tracker_http_client_new (void);
+
+GInputStream *
+tracker_http_client_send_message (TrackerHttpClient        *client,
+                                  const gchar              *uri,
+                                  const gchar              *query,
+                                  guint                     formats,
+                                  GCancellable             *cancellable,
+                                  TrackerSerializerFormat  *format,
+                                  GError                  **error);
+
+void
+tracker_http_client_send_message_async (TrackerHttpClient   *client,
+                                        const gchar         *uri,
+                                        const gchar         *query,
+                                        guint                formats,
+                                        GCancellable        *cancellable,
+                                        GAsyncReadyCallback  callback,
+                                        gpointer             user_data);
+
+GInputStream *
+tracker_http_client_send_message_finish (TrackerHttpClient        *client,
+                                         GAsyncResult             *res,
+                                         TrackerSerializerFormat  *format,
+                                         GError                  **error);
+
+#endif /* TRACKER_HTTP_H */


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