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




commit 6536c64d23522cb2927ec54d1c5075f221d75c31
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 | 313 ++++++++++++++++++++++++++++
 src/libtracker-sparql/remote/tracker-http.h | 101 +++++++++
 4 files changed, 419 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..489e83a8a
--- /dev/null
+++ b/src/libtracker-sparql/remote/tracker-http.c
@@ -0,0 +1,313 @@
+#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..1411e5308
--- /dev/null
+++ b/src/libtracker-sparql/remote/tracker-http.h
@@ -0,0 +1,101 @@
+#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]