[tracker/wip/carlosg/remote-module-reduction: 1/6] libtracker-sparql: Add base http helper object definitions
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/remote-module-reduction: 1/6] libtracker-sparql: Add base http helper object definitions
- Date: Sun, 24 Apr 2022 15:25:48 +0000 (UTC)
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]