[tracker/wip/carlosg/remote-module-reduction: 5/8] libtracker-sparql: Port TrackerEndpointHttp to new HTTP module




commit 54d0db947c34b75cebd0de70ce07acd0df2ef98d
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Apr 23 14:01:12 2022 +0200

    libtracker-sparql: Port TrackerEndpointHttp to new HTTP module
    
    Use TrackerHttpServer to implement HTTP endpoints, and remove all
    soup specific code. This also means the TrackerEndpointHttp object
    and type can move out of the elder soup modules, and into the main
    library code. All soup 2/3 handling will stay underneath.

 src/libtracker-sparql/meson.build             |   2 +-
 src/libtracker-sparql/tracker-endpoint-http.c | 250 ++++++--------------------
 src/libtracker-sparql/tracker-remote-module.c |  35 +---
 3 files changed, 57 insertions(+), 230 deletions(-)
---
diff --git a/src/libtracker-sparql/meson.build b/src/libtracker-sparql/meson.build
index 001c9fba7..9192fccfe 100644
--- a/src/libtracker-sparql/meson.build
+++ b/src/libtracker-sparql/meson.build
@@ -27,6 +27,7 @@ libtracker_sparql_c_sources = files(
     'tracker-cursor.c',
     'tracker-endpoint.c',
     'tracker-endpoint-dbus.c',
+    'tracker-endpoint-http.c',
     'tracker-error.c',
     'tracker-namespace-manager.c',
     'tracker-notifier.c',
@@ -151,7 +152,6 @@ tracker_sparql_dep = declare_dependency(
 )
 
 libtracker_sparql_remote_c_sources = files(
-    'tracker-endpoint-http.c',
     'remote/tracker-remote-statement.c',
     'tracker-serializer.c',
     'tracker-serializer-json.c',
diff --git a/src/libtracker-sparql/tracker-endpoint-http.c b/src/libtracker-sparql/tracker-endpoint-http.c
index 6248284e9..60f308793 100644
--- a/src/libtracker-sparql/tracker-endpoint-http.c
+++ b/src/libtracker-sparql/tracker-endpoint-http.c
@@ -55,13 +55,11 @@
 #include "tracker-serializer.h"
 #include "tracker-private.h"
 
-#include <libsoup/soup.h>
-
-#define SERVER_HEADER "Tracker " PACKAGE_VERSION " (https://gitlab.gnome.org/GNOME/tracker/issues/)"
+#include "remote/tracker-http.h"
 
 struct _TrackerEndpointHttp {
        TrackerEndpoint parent_instance;
-       SoupServer *server;
+       TrackerHttpServer *server;
        GTlsCertificate *certificate;
        guint port;
        GCancellable *cancellable;
@@ -69,11 +67,7 @@ struct _TrackerEndpointHttp {
 
 typedef struct {
        TrackerEndpoint *endpoint;
-#if SOUP_CHECK_VERSION (2, 99, 2)
-        SoupServerMessage *message;
-#else
-       SoupMessage *message;
-#endif
+       TrackerHttpRequest *request;
        GInputStream *istream;
        GTask *task;
        TrackerSerializerFormat format;
@@ -91,11 +85,6 @@ enum {
        N_PROPS
 };
 
-#define XML_TYPE "application/sparql-results+xml"
-#define JSON_TYPE "application/sparql-results+json"
-#define TTL_TYPE "text/turtle"
-#define TRIG_TYPE "application/trig"
-
 static GParamSpec *props[N_PROPS];
 static guint signals[N_SIGNALS];
 
@@ -111,81 +100,6 @@ request_free (Request *request)
        g_free (request);
 }
 
-static void
-handle_request_in_thread (GTask        *task,
-                          gpointer      source_object,
-                          gpointer      task_data,
-                          GCancellable *cancellable)
-{
-       Request *request = task_data;
-       gchar buffer[1000];
-       SoupMessageBody *message_body;
-       GError *error = NULL;
-       gssize count;
-
-#if SOUP_CHECK_VERSION (2, 99, 2)
-        message_body = soup_server_message_get_response_body (request->message);
-#else
-        message_body = request->message->response_body;
-#endif
-
-       for (;;) {
-               count = g_input_stream_read (request->istream,
-                                            buffer, sizeof (buffer),
-                                            cancellable, &error);
-               if (count < 0) {
-                       g_task_return_error (task, error);
-                       break;
-               }
-
-               soup_message_body_append (message_body,
-                                         SOUP_MEMORY_COPY,
-                                         buffer, count);
-
-               if ((gsize) count < sizeof (buffer)) {
-                       break;
-               }
-       }
-
-       g_input_stream_close (request->istream, cancellable, NULL);
-       soup_message_body_complete (message_body);
-       g_task_return_boolean (task, TRUE);
-}
-
-static void
-request_finished_cb (GObject      *object,
-                     GAsyncResult *result,
-                     gpointer      user_data)
-{
-       Request *request = user_data;
-       TrackerEndpointHttp *endpoint_http;
-       GError *error = NULL;
-
-       endpoint_http = TRACKER_ENDPOINT_HTTP (request->endpoint);
-
-       if (!g_task_propagate_boolean (G_TASK (result), &error)) {
-#if SOUP_CHECK_VERSION (2, 99, 2)
-                soup_server_message_set_status (request->message, 500,
-                                                error ? error->message :
-                                                "No error message");
-#else
-               soup_message_set_status_full (request->message, 500,
-                                             error ? error->message :
-                                             "No error message");
-#endif
-               g_clear_error (&error);
-       } else {
-#if SOUP_CHECK_VERSION (2, 99, 2)
-                soup_server_message_set_status (request->message, 200, NULL);
-#else
-               soup_message_set_status (request->message, 200);
-#endif
-       }
-
-       soup_server_unpause_message (endpoint_http->server, request->message);
-       request_free (request);
-}
-
 static void
 query_async_cb (GObject      *object,
                 GAsyncResult *result,
@@ -194,150 +108,98 @@ query_async_cb (GObject      *object,
        TrackerEndpointHttp *endpoint_http;
        TrackerSparqlCursor *cursor;
        Request *request = user_data;
+       GInputStream *stream;
        GError *error = NULL;
 
        endpoint_http = TRACKER_ENDPOINT_HTTP (request->endpoint);
        cursor = tracker_sparql_connection_query_finish (TRACKER_SPARQL_CONNECTION (object),
                                                         result, &error);
        if (error) {
-#if SOUP_CHECK_VERSION (2, 99, 2)
-                soup_server_message_set_status (request->message, 500, error->message);
-#else
-               soup_message_set_status_full (request->message, 500, error->message);
-#endif
-               soup_server_unpause_message (endpoint_http->server, request->message);
+               tracker_http_server_error (endpoint_http->server,
+                                          request->request,
+                                          500,
+                                          error->message);
                request_free (request);
+               g_error_free (error);
                return;
        }
 
-       request->istream = tracker_serializer_new (cursor, request->format);
-       request->task = g_task_new (endpoint_http, endpoint_http->cancellable,
-                                   request_finished_cb, request);
-       g_task_set_task_data (request->task, request, NULL);
-       g_object_unref (cursor);
-
-       g_task_run_in_thread (request->task, handle_request_in_thread);
+       stream = tracker_serializer_new (cursor, request->format);
+       /* Consumes the input stream */
+       tracker_http_server_response (endpoint_http->server,
+                                     request->request,
+                                     request->format,
+                                     stream);
+       request_free (request);
 }
 
-#if SOUP_CHECK_VERSION (2, 99, 2)
 static gboolean
-pick_format (SoupServerMessage       *message,
+pick_format (guint                    formats,
              TrackerSerializerFormat *format)
-#else
-static gboolean
-pick_format (SoupMessage             *message,
-             TrackerSerializerFormat *format)
-#endif
 {
-       SoupMessageHeaders *request_headers, *response_headers;
-
-#if SOUP_CHECK_VERSION (2, 99, 2)
-        request_headers = soup_server_message_get_request_headers (message);
-        response_headers = soup_server_message_get_response_headers (message);
-#else
-        request_headers = message->request_headers;
-        response_headers = message->response_headers;
-#endif
-
-       if (soup_message_headers_header_contains (request_headers, "Accept", JSON_TYPE)) {
-               soup_message_headers_set_content_type (response_headers, JSON_TYPE, NULL);
-               *format = TRACKER_SERIALIZER_FORMAT_JSON;
-               return TRUE;
-       } else if (soup_message_headers_header_contains (request_headers, "Accept", XML_TYPE)) {
-               soup_message_headers_set_content_type (response_headers, XML_TYPE, NULL);
-               *format = TRACKER_SERIALIZER_FORMAT_XML;
-               return TRUE;
-       } else if (soup_message_headers_header_contains (request_headers, "Accept", TTL_TYPE)) {
-               soup_message_headers_set_content_type (response_headers, TTL_TYPE, NULL);
-               *format = TRACKER_SERIALIZER_FORMAT_TTL;
-               return TRUE;
-       } else if (soup_message_headers_header_contains (request_headers, "Accept", TRIG_TYPE)) {
-               soup_message_headers_set_content_type (response_headers, TRIG_TYPE, NULL);
-               *format = TRACKER_SERIALIZER_FORMAT_TRIG;
-               return TRUE;
-       } else {
-               return FALSE;
+       TrackerSerializerFormat i;
+
+       for (i = 0; i < TRACKER_N_SERIALIZER_FORMATS; i++) {
+               if ((formats & (1 << i)) != 0) {
+                       *format = i;
+                       return TRUE;
+               }
        }
 
        return FALSE;
 }
 
-#if SOUP_CHECK_VERSION (2, 99, 2)
 static void
-server_callback (SoupServer        *server,
-                SoupServerMessage *message,
-                 const char        *path,
-                GHashTable        *query,
-                 gpointer           user_data)
-#else
-static void
-server_callback (SoupServer        *server,
-                 SoupMessage       *message,
-                 const char        *path,
-                 GHashTable        *query,
-                 SoupClientContext *client,
-                 gpointer           user_data)
-#endif
+http_server_request_cb (TrackerHttpServer  *server,
+                        GSocketAddress     *remote_address,
+                        const gchar        *path,
+                        GHashTable         *params,
+                        guint               formats,
+                        TrackerHttpRequest *request,
+                        gpointer            user_data)
 {
        TrackerEndpoint *endpoint = user_data;
        TrackerSparqlConnection *conn;
        TrackerSerializerFormat format;
-       GSocketAddress *remote_address;
        gboolean block = FALSE;
        const gchar *sparql;
-       Request *request;
+       Request *data;
 
-#if SOUP_CHECK_VERSION (2, 99, 2)
-        remote_address = soup_server_message_get_remote_address (message);
-#else
-       remote_address = soup_client_context_get_remote_address (client);
-#endif
        if (remote_address) {
                g_signal_emit (endpoint, signals[BLOCK_REMOTE_ADDRESS], 0,
                               remote_address, &block);
        }
 
        if (block) {
-#if SOUP_CHECK_VERSION (2, 99, 2)
-                soup_server_message_set_status (message, 500, "Remote address disallowed");
-#else
-               soup_message_set_status_full (message, 500, "Remote address disallowed");
-#endif
+               tracker_http_server_error (server, request, 500,
+                                          "Remote address disallowed");
                return;
        }
 
-       sparql = g_hash_table_lookup (query, "query");
+       sparql = g_hash_table_lookup (params, "query");
        if (!sparql) {
-#if SOUP_CHECK_VERSION (2, 99, 2)
-                soup_server_message_set_status (message, 500, "No query given");
-#else
-               soup_message_set_status_full (message, 500, "No query given");
-#endif
+               tracker_http_server_error (server, request, 500,
+                                          "No query given");
                return;
        }
 
-       if (!pick_format (message, &format)) {
-#if SOUP_CHECK_VERSION (2, 99, 2)
-                soup_server_message_set_status (message, 500, "No recognized accepted formats");
-#else
-               soup_message_set_status_full (message, 500, "No recognized accepted formats");
-#endif
+       if (!pick_format (formats, &format)) {
+               tracker_http_server_error (server, request, 500,
+                                          "No recognized accepted formats");
                return;
        }
 
-       request = g_new0 (Request, 1);
-       request->endpoint = endpoint;
-       request->message = message;
-       request->format = format;
+       data = g_new0 (Request, 1);
+       data->endpoint = endpoint;
+       data->request = request;
+       data->format = format;
 
        conn = tracker_endpoint_get_sparql_connection (endpoint);
        tracker_sparql_connection_query_async (conn,
                                               sparql,
                                               NULL,
                                               query_async_cb,
-                                              request);
-
-       soup_server_pause_message (server, message);
+                                              data);
 }
 
 static gboolean
@@ -349,18 +211,16 @@ tracker_endpoint_http_initable_init (GInitable     *initable,
        TrackerEndpointHttp *endpoint_http = TRACKER_ENDPOINT_HTTP (endpoint);
 
        endpoint_http->server =
-               soup_server_new ("tls-certificate", endpoint_http->certificate,
-                                "server-header", SERVER_HEADER,
-                                NULL);
-       soup_server_add_handler (endpoint_http->server,
-                                "/sparql",
-                                server_callback,
-                                initable,
-                                NULL);
-
-       return soup_server_listen_all (endpoint_http->server,
-                                      endpoint_http->port,
-                                      0, error);
+               tracker_http_server_new (endpoint_http->port,
+                                        endpoint_http->certificate,
+                                        cancellable,
+                                        error);
+       if (!endpoint_http->server)
+               return FALSE;
+
+       g_signal_connect (endpoint_http->server, "request",
+                         G_CALLBACK (http_server_request_cb), initable);
+       return TRUE;
 }
 
 static void
diff --git a/src/libtracker-sparql/tracker-remote-module.c b/src/libtracker-sparql/tracker-remote-module.c
index 2ca0fd181..16a88655b 100644
--- a/src/libtracker-sparql/tracker-remote-module.c
+++ b/src/libtracker-sparql/tracker-remote-module.c
@@ -10,13 +10,6 @@
 
 static gboolean initialized = FALSE;
 
-GType (* remote_endpoint_get_type) (void) = NULL;
-
-TrackerEndpoint * (* remote_endpoint_new) (TrackerSparqlConnection  *sparql_connection,
-                                           guint                     port,
-                                           GTlsCertificate          *certificate,
-                                           GCancellable             *cancellable,
-                                           GError                  **error) = NULL;
 TrackerSparqlConnection * (* remote_connection_new) (const gchar *url_base) = NULL;
 
 static void
@@ -66,9 +59,7 @@ tracker_init_remote (void)
                if (!remote_module)
                        continue;
 
-               if (!g_module_symbol (remote_module, "tracker_endpoint_http_get_type", (gpointer *) 
&remote_endpoint_get_type) ||
-                   !g_module_symbol (remote_module, "tracker_endpoint_http_new", (gpointer *) 
&remote_endpoint_new) ||
-                   !g_module_symbol (remote_module, "tracker_remote_connection_new", (gpointer *) 
&remote_connection_new)) {
+               if (!g_module_symbol (remote_module, "tracker_remote_connection_new", (gpointer *) 
&remote_connection_new)) {
                        g_clear_pointer (&remote_module, g_module_close);
                        continue;
                }
@@ -82,30 +73,6 @@ tracker_init_remote (void)
        g_assert_not_reached ();
 }
 
-GType
-tracker_endpoint_http_get_type (void)
-{
-       tracker_init_remote ();
-
-       return remote_endpoint_get_type ();
-}
-
-TrackerEndpointHttp *
-tracker_endpoint_http_new (TrackerSparqlConnection  *sparql_connection,
-                           guint                     port,
-                           GTlsCertificate          *certificate,
-                           GCancellable             *cancellable,
-                           GError                  **error)
-{
-       tracker_init_remote ();
-
-       return (TrackerEndpointHttp *) remote_endpoint_new (sparql_connection,
-                                                           port,
-                                                           certificate,
-                                                           cancellable,
-                                                           error);
-}
-
 TrackerSparqlConnection *
 tracker_sparql_connection_remote_new (const gchar *url_base)
 {


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