[tracker/wip/carlosg/remote-module-reduction: 2/7] 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: 2/7] libtracker-sparql: Add base http helper object definitions
- Date: Sun, 24 Apr 2022 11:19:52 +0000 (UTC)
commit b3c8b72617d86a4676b3aabf43d11a5c1b376d87
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 | 303 ++++++++++++++++++++++++++++
src/libtracker-sparql/remote/tracker-http.h | 101 ++++++++++
4 files changed, 409 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..5c38de28c
--- /dev/null
+++ b/src/libtracker-sparql/remote/tracker-http.c
@@ -0,0 +1,303 @@
+#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]);
+ }
+
+ remote_module = g_module_open (module_path,
+ G_MODULE_BIND_LAZY |
+ G_MODULE_BIND_LOCAL);
+ g_free (module_path);
+
+ if (!remote_module)
+ continue;
+
+ if (!g_module_symbol (remote_module, "initialize_types", (gpointer *) &init_func)) {
+ 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]