[libsoup/carlosgc/server-http2: 6/13] server: add SoupServerMessageIO interface




commit 85ef40fe5af14a35622325edf298b2a901351cbb
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Thu Jul 7 15:00:06 2022 +0200

    server: add SoupServerMessageIO interface

 libsoup/meson.build                                |   1 +
 .../server/http1/soup-server-message-io-http1.c    | 186 +++++++++++----------
 .../server/http1/soup-server-message-io-http1.h    |   5 +-
 libsoup/server/soup-server-connection.c            |  12 +-
 libsoup/server/soup-server-connection.h            |   5 +-
 libsoup/server/soup-server-message-io.c            |  62 +++++++
 libsoup/server/soup-server-message-io.h            |  47 ++++++
 libsoup/server/soup-server-message-private.h       |  18 +-
 libsoup/server/soup-server-message.c               |  43 ++++-
 libsoup/server/soup-server.c                       |   9 +-
 10 files changed, 265 insertions(+), 123 deletions(-)
---
diff --git a/libsoup/meson.build b/libsoup/meson.build
index 3ea9a5c3..48217952 100644
--- a/libsoup/meson.build
+++ b/libsoup/meson.build
@@ -52,6 +52,7 @@ soup_sources = [
   'server/soup-server.c',
   'server/soup-server-connection.c',
   'server/soup-server-message.c',
+  'server/soup-server-message-io.c',
 
   'websocket/soup-websocket.c',
   'websocket/soup-websocket-connection.c',
diff --git a/libsoup/server/http1/soup-server-message-io-http1.c 
b/libsoup/server/http1/soup-server-message-io-http1.c
index 4ac9ac66..ad035b8a 100644
--- a/libsoup/server/http1/soup-server-message-io-http1.c
+++ b/libsoup/server/http1/soup-server-message-io-http1.c
@@ -16,7 +16,9 @@
 #include "soup-body-input-stream.h"
 #include "soup-body-output-stream.h"
 #include "soup-filter-input-stream.h"
+#include "soup-message-io-data.h"
 #include "soup-message-headers-private.h"
+#include "soup-server-message-private.h"
 #include "soup-misc.h"
 
 typedef struct {
@@ -32,13 +34,15 @@ typedef struct {
        GMainContext *async_context;
 } SoupMessageIOHTTP1;
 
-struct _SoupServerMessageIOData {
+typedef struct {
+        SoupServerMessageIO iface;
+
         GIOStream *iostream;
         GInputStream *istream;
         GOutputStream *ostream;
 
         SoupMessageIOHTTP1 *msg_io;
-};
+} SoupServerMessageIOHTTP1;
 
 #define RESPONSE_BLOCK_SIZE 8192
 #define HEADER_SIZE_LIMIT (64 * 1024)
@@ -54,7 +58,6 @@ soup_message_io_http1_free (SoupMessageIOHTTP1 *msg_io)
                 msg_io->unpause_source = NULL;
         }
 
-        soup_server_message_set_io_data (msg_io->msg, NULL);
         g_clear_object (&msg_io->msg);
         g_clear_pointer (&msg_io->async_context, g_main_context_unref);
         g_clear_pointer (&msg_io->write_chunk, g_bytes_unref);
@@ -62,30 +65,26 @@ soup_message_io_http1_free (SoupMessageIOHTTP1 *msg_io)
         g_free (msg_io);
 }
 
-void
-soup_server_message_io_data_free (SoupServerMessageIOData *io)
+static void
+soup_server_message_io_http1_destroy (SoupServerMessageIO *iface)
 {
-        if (!io)
-                return;
+        SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface;
 
         g_clear_object (&io->iostream);
         g_clear_pointer (&io->msg_io, soup_message_io_http1_free);
 
-        g_slice_free (SoupServerMessageIOData, io);
+        g_slice_free (SoupServerMessageIOHTTP1, io);
 }
 
-void
-soup_server_message_io_finished (SoupServerMessage *msg)
+static void
+soup_server_message_io_http1_finished (SoupServerMessageIO *iface,
+                                       SoupServerMessage   *msg)
 {
-       SoupServerMessageIOData *io;
+        SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface;
         SoupMessageIOCompletionFn completion_cb;
         gpointer completion_data;
         SoupMessageIOCompletion completion;
 
-       io = soup_server_message_get_io_data (msg);
-        if (!io)
-                return;
-
        completion_cb = io->msg_io->base.completion_cb;
         completion_data = io->msg_io->base.completion_data;
 
@@ -97,28 +96,28 @@ soup_server_message_io_finished (SoupServerMessage *msg)
 
         g_object_ref (msg);
         g_clear_pointer (&io->msg_io, soup_message_io_http1_free);
-        soup_server_message_set_io_data (msg, NULL);
        if (completion_cb)
                 completion_cb (G_OBJECT (msg), completion, completion_data);
         g_object_unref (msg);
 }
 
-GIOStream *
-soup_server_message_io_steal (SoupServerMessage *msg)
+static GIOStream *
+soup_server_message_io_http1_steal (SoupServerMessageIO *iface)
 {
-        SoupServerMessageIOData *io;
+        SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface;
+        SoupServerMessage *msg;
         SoupMessageIOCompletionFn completion_cb;
        gpointer completion_data;
        GIOStream *iostream;
 
-        io = soup_server_message_get_io_data (msg);
-        if (!io || !io->iostream)
+        if (!io->iostream)
                 return NULL;
 
         iostream = g_object_ref (io->iostream);
         completion_cb = io->msg_io->base.completion_cb;
        completion_data = io->msg_io->base.completion_data;
 
+        msg = io->msg_io->msg;
         g_object_ref (msg);
         g_clear_pointer (&io->msg_io, soup_message_io_http1_free);
         if (completion_cb)
@@ -135,10 +134,10 @@ closed_async (GObject      *source,
 {
         GOutputStream *body_ostream = G_OUTPUT_STREAM (source);
         SoupServerMessage *msg = user_data;
-        SoupServerMessageIOData *io;
+        SoupServerMessageIOHTTP1 *io;
         GCancellable *async_wait;
 
-        io = soup_server_message_get_io_data (msg);
+        io = (SoupServerMessageIOHTTP1 *)soup_server_message_get_io_data (msg);
         if (!io || !io->msg_io || !io->msg_io->base.async_wait || io->msg_io->base.body_ostream != 
body_ostream) {
                 g_object_unref (msg);
                 return;
@@ -358,10 +357,10 @@ write_headers (SoupServerMessage  *msg,
  * socket not writable, write is complete, etc).
  */
 static gboolean
-io_write (SoupServerMessage *msg,
-          GError           **error)
+io_write (SoupServerMessageIOHTTP1 *server_io,
+          GError                  **error)
 {
-        SoupServerMessageIOData *server_io = soup_server_message_get_io_data (msg);
+        SoupServerMessage *msg = server_io->msg_io->msg;
        SoupMessageIOData *io = &server_io->msg_io->base;
         GBytes *chunk;
         gssize nwrote;
@@ -427,7 +426,7 @@ io_write (SoupServerMessage *msg,
                         /* If this was "101 Switching Protocols", then
                          * the server probably stole the connection...
                          */
-                        if (server_io != soup_server_message_get_io_data (msg))
+                        if ((SoupServerMessageIO *)server_io != soup_server_message_get_io_data (msg))
                                 return FALSE;
 
                         soup_server_message_cleanup_response (msg);
@@ -467,7 +466,7 @@ io_write (SoupServerMessage *msg,
                         server_io->msg_io->write_chunk = soup_message_body_get_chunk 
(soup_server_message_get_response_body (msg),
                                                                                       
server_io->msg_io->write_body_offset);
                         if (!server_io->msg_io->write_chunk) {
-                                soup_server_message_io_pause (msg);
+                                soup_server_message_pause (msg);
                                 return FALSE;
                         }
                         if (!g_bytes_get_size (server_io->msg_io->write_chunk)) {
@@ -679,10 +678,10 @@ parse_headers (SoupServerMessage *msg,
  * socket not readable, read is complete, etc).
  */
 static gboolean
-io_read (SoupServerMessage *msg,
-         GError           **error)
+io_read (SoupServerMessageIOHTTP1 *server_io,
+         GError                  **error)
 {
-        SoupServerMessageIOData *server_io = soup_server_message_get_io_data (msg);
+        SoupServerMessage *msg = server_io->msg_io->msg;
        SoupMessageIOData *io = &server_io->msg_io->base;
         gssize nread;
         guint status;
@@ -796,12 +795,12 @@ io_read (SoupServerMessage *msg,
 }
 
 static gboolean
-io_run_until (SoupServerMessage *msg,
-              SoupMessageIOState read_state,
-              SoupMessageIOState write_state,
-              GError           **error)
+io_run_until (SoupServerMessageIOHTTP1 *server_io,
+              SoupMessageIOState        read_state,
+              SoupMessageIOState        write_state,
+              GError                  **error)
 {
-        SoupServerMessageIOData *server_io = soup_server_message_get_io_data (msg);
+        SoupServerMessage *msg = server_io->msg_io->msg;
        SoupMessageIOData *io = &server_io->msg_io->base;
         gboolean progress = TRUE, done;
         GError *my_error = NULL;
@@ -811,13 +810,13 @@ io_run_until (SoupServerMessage *msg,
 
         g_object_ref (msg);
 
-        while (progress && soup_server_message_get_io_data (msg) == server_io && !io->paused && 
!io->async_wait &&
+        while (progress && soup_server_message_get_io_data (msg) == (SoupServerMessageIO *)server_io && 
!io->paused && !io->async_wait &&
                (io->read_state < read_state || io->write_state < write_state)) {
 
                 if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state))
-                        progress = io_read (msg, &my_error);
+                        progress = io_read (server_io, &my_error);
                 else if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->write_state))
-                        progress = io_write (msg, &my_error);
+                        progress = io_write (server_io, &my_error);
                 else
                         progress = FALSE;
         }
@@ -828,7 +827,7 @@ io_run_until (SoupServerMessage *msg,
                 return FALSE;
         }
 
-       if (soup_server_message_get_io_data (msg) != server_io) {
+       if (soup_server_message_get_io_data (msg) != (SoupServerMessageIO *)server_io) {
                 g_object_unref (msg);
                 return FALSE;
         }
@@ -848,20 +847,20 @@ io_run_until (SoupServerMessage *msg,
         return done;
 }
 
-static void io_run (SoupServerMessage *msg);
+static void io_run (SoupServerMessageIOHTTP1 *server_io);
 
 static gboolean
 io_run_ready (SoupServerMessage *msg,
               gpointer           user_data)
 {
-        io_run (msg);
+        io_run ((SoupServerMessageIOHTTP1 *)soup_server_message_get_io_data (msg));
         return FALSE;
 }
 
 static void
-io_run (SoupServerMessage *msg)
+io_run (SoupServerMessageIOHTTP1 *server_io)
 {
-        SoupServerMessageIOData *server_io = soup_server_message_get_io_data (msg);
+        SoupServerMessage *msg = server_io->msg_io->msg;
        SoupMessageIOData *io = &server_io->msg_io->base;
         GError *error = NULL;
 
@@ -872,11 +871,11 @@ io_run (SoupServerMessage *msg)
         }
 
         g_object_ref (msg);
-        if (io_run_until (msg,
+        if (io_run_until (server_io,
                           SOUP_MESSAGE_IO_STATE_DONE,
                           SOUP_MESSAGE_IO_STATE_DONE,
                           &error)) {
-                soup_server_message_io_finished (msg);
+                soup_server_message_finish (msg);
         } else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
                 g_clear_error (&error);
                 io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg),
@@ -886,33 +885,21 @@ io_run (SoupServerMessage *msg)
                                                                 (SoupMessageIOSourceFunc)io_run_ready,
                                                                 NULL);
                 g_source_attach (io->io_source, server_io->msg_io->async_context);
-        } else if (soup_server_message_get_io_data (msg) == server_io) {
+        } else if (soup_server_message_get_io_data (msg) == (SoupServerMessageIO *)server_io) {
                soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, error ? 
error->message : NULL);
-               soup_server_message_io_finished (msg);
+               soup_server_message_finish (msg);
        }
        g_object_unref (msg);
        g_clear_error (&error);
 }
 
-SoupServerMessageIOData *
-soup_server_message_io_http1_new (GIOStream *iostream)
-{
-        SoupServerMessageIOData *io;
-
-        io = g_slice_new0 (SoupServerMessageIOData);
-        io->iostream = g_object_ref (iostream);
-        io->istream = g_io_stream_get_input_stream (io->iostream);
-        io->ostream = g_io_stream_get_output_stream (io->iostream);
-
-        return io;
-}
-
-void
-soup_server_message_io_read_request (SoupServerMessageIOData  *io,
-                                     SoupServerMessage        *msg,
-                                     SoupMessageIOCompletionFn completion_cb,
-                                     gpointer                  user_data)
+static void
+soup_server_message_io_http1_read_request (SoupServerMessageIO      *iface,
+                                           SoupServerMessage        *msg,
+                                           SoupMessageIOCompletionFn completion_cb,
+                                           gpointer                  user_data)
 {
+        SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface;
         SoupMessageIOHTTP1 *msg_io;
 
         msg_io = g_new0 (SoupMessageIOHTTP1, 1);
@@ -930,15 +917,16 @@ soup_server_message_io_read_request (SoupServerMessageIOData  *io,
         msg_io->async_context = g_main_context_ref_thread_default ();
         io->msg_io = msg_io;
 
-        io_run (msg);
+        io_run (io);
 }
 
-void
-soup_server_message_io_pause (SoupServerMessage *msg)
+static void
+soup_server_message_io_http1_pause (SoupServerMessageIO *iface,
+                                    SoupServerMessage   *msg)
 {
-       SoupServerMessageIOData *io = soup_server_message_get_io_data (msg);
+        SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface;
 
-        g_return_if_fail (io != NULL);
+        g_assert (io->msg_io && io->msg_io->msg == msg);
 
        if (io->msg_io->unpause_source) {
                 g_source_destroy (io->msg_io->unpause_source);
@@ -949,38 +937,66 @@ soup_server_message_io_pause (SoupServerMessage *msg)
 }
 
 static gboolean
-io_unpause_internal (gpointer msg)
+io_unpause_internal (SoupServerMessageIOHTTP1 *io)
 {
-        SoupServerMessageIOData *io = soup_server_message_get_io_data (msg);
-
-       g_return_val_if_fail (io != NULL && io->msg_io != NULL, FALSE);
+       g_assert (io != NULL && io->msg_io != NULL);
 
        g_clear_pointer (&io->msg_io->unpause_source, g_source_unref);
        soup_message_io_data_unpause (&io->msg_io->base);
         if (io->msg_io->base.io_source)
                return FALSE;
 
-        io_run (msg);
+        io_run (io);
        return FALSE;
 }
 
-void
-soup_server_message_io_unpause (SoupServerMessage *msg)
+static void
+soup_server_message_io_http1_unpause (SoupServerMessageIO *iface,
+                                      SoupServerMessage   *msg)
 {
-       SoupServerMessageIOData *io = soup_server_message_get_io_data (msg);
+        SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface;
 
-        g_return_if_fail (io != NULL);
+        g_assert (io->msg_io && io->msg_io->msg == msg);
 
         if (!io->msg_io->unpause_source) {
                io->msg_io->unpause_source = soup_add_completion_reffed (io->msg_io->async_context,
-                                                                         io_unpause_internal, msg, NULL);
+                                                                         (GSourceFunc)io_unpause_internal,
+                                                                         io, NULL);
         }
 }
 
-gboolean
-soup_server_message_is_io_paused (SoupServerMessage *msg)
+static gboolean
+soup_server_message_io_http1_is_paused (SoupServerMessageIO *iface,
+                                        SoupServerMessage   *msg)
 {
-       SoupServerMessageIOData *io = soup_server_message_get_io_data (msg);
+        SoupServerMessageIOHTTP1 *io = (SoupServerMessageIOHTTP1 *)iface;
+
+        g_assert (io->msg_io && io->msg_io->msg == msg);
+
+       return io->msg_io->base.paused;
+}
+
+static const SoupServerMessageIOFuncs io_funcs = {
+        soup_server_message_io_http1_destroy,
+        soup_server_message_io_http1_finished,
+        soup_server_message_io_http1_steal,
+        soup_server_message_io_http1_read_request,
+        soup_server_message_io_http1_pause,
+        soup_server_message_io_http1_unpause,
+        soup_server_message_io_http1_is_paused
+};
+
+SoupServerMessageIO *
+soup_server_message_io_http1_new (SoupServerConnection *conn)
+{
+        SoupServerMessageIOHTTP1 *io;
+
+        io = g_slice_new0 (SoupServerMessageIOHTTP1);
+        io->iostream = g_object_ref (soup_server_connection_get_iostream (conn));
+        io->istream = g_io_stream_get_input_stream (io->iostream);
+        io->ostream = g_io_stream_get_output_stream (io->iostream);
+
+        io->iface.funcs = &io_funcs;
 
-       return io && io->msg_io && io->msg_io->base.paused;
+        return (SoupServerMessageIO *)io;
 }
diff --git a/libsoup/server/http1/soup-server-message-io-http1.h 
b/libsoup/server/http1/soup-server-message-io-http1.h
index cc40af56..a9d34da9 100644
--- a/libsoup/server/http1/soup-server-message-io-http1.h
+++ b/libsoup/server/http1/soup-server-message-io-http1.h
@@ -5,6 +5,7 @@
 
 #pragma once
 
-#include "soup-server-message-private.h"
+#include "soup-server-connection.h"
+#include "soup-server-message-io.h"
 
-SoupServerMessageIOData *soup_server_message_io_http1_new (GIOStream *iostream);
+SoupServerMessageIO *soup_server_message_io_http1_new (SoupServerConnection *conn);
diff --git a/libsoup/server/soup-server-connection.c b/libsoup/server/soup-server-connection.c
index b76b33da..d84bd8d5 100644
--- a/libsoup/server/soup-server-connection.c
+++ b/libsoup/server/soup-server-connection.c
@@ -55,7 +55,7 @@ typedef struct {
         GSocket *socket;
         GIOStream *conn;
         GIOStream *iostream;
-        SoupServerMessageIOData *io_data;
+        SoupServerMessageIO *io_data;
 
         GSocketAddress *local_addr;
         GSocketAddress *remote_addr;
@@ -83,7 +83,7 @@ disconnect_internal (SoupServerConnection *conn)
         g_signal_handlers_disconnect_by_data (priv->conn, conn);
         g_clear_object (&priv->conn);
 
-        g_clear_pointer (&priv->io_data, soup_server_message_io_data_free);
+        g_clear_pointer (&priv->io_data, soup_server_message_io_destroy);
 }
 
 static void
@@ -95,7 +95,7 @@ soup_server_connection_finalize (GObject *object)
         if (priv->conn)
                 disconnect_internal (conn);
 
-        g_clear_pointer (&priv->io_data, soup_server_message_io_data_free);
+        g_clear_pointer (&priv->io_data, soup_server_message_io_destroy);
 
         g_clear_object (&priv->iostream);
 
@@ -125,7 +125,7 @@ soup_server_connection_set_property (GObject      *object,
                 priv->conn = g_value_dup_object (value);
                 if (priv->conn) {
                         priv->iostream = soup_io_stream_new (priv->conn, FALSE);
-                        priv->io_data = soup_server_message_io_http1_new (priv->iostream);
+                        priv->io_data = soup_server_message_io_http1_new (conn);
                 }
                 break;
         case PROP_LOCAL_ADDRESS:
@@ -337,7 +337,7 @@ soup_server_connection_new_for_connection (GIOStream      *connection,
                              NULL);
 }
 
-SoupServerMessageIOData *
+SoupServerMessageIO *
 soup_server_connection_get_io_data (SoupServerConnection *conn)
 {
         SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn);
@@ -351,7 +351,7 @@ soup_server_connection_create_io_data (SoupServerConnection *conn)
         SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn);
 
         g_assert (!priv->io_data);
-        priv->io_data = soup_server_message_io_http1_new (priv->iostream);
+        priv->io_data = soup_server_message_io_http1_new (conn);
 }
 
 static gboolean
diff --git a/libsoup/server/soup-server-connection.h b/libsoup/server/soup-server-connection.h
index 5f14cbfe..acc52a82 100644
--- a/libsoup/server/soup-server-connection.h
+++ b/libsoup/server/soup-server-connection.h
@@ -7,12 +7,11 @@
 #pragma once
 
 #include "soup-types.h"
+#include "soup-server-message-io.h"
 #include <gio/gio.h>
 
 G_BEGIN_DECLS
 
-typedef struct _SoupServerMessageIOData SoupServerMessageIOData;
-
 #define SOUP_TYPE_SERVER_CONNECTION (soup_server_connection_get_type ())
 G_DECLARE_FINAL_TYPE (SoupServerConnection, soup_server_connection, SOUP, SERVER_CONNECTION, GObject)
 
@@ -30,7 +29,7 @@ void                  soup_server_connection_setup_async                     (So
 gboolean              soup_server_connection_setup_finish                    (SoupServerConnection  *conn,
                                                                               GAsyncResult          *result,
                                                                               GError               **error);
-SoupServerMessageIOData *soup_server_connection_get_io_data                  (SoupServerConnection  *conn);
+SoupServerMessageIO  *soup_server_connection_get_io_data                     (SoupServerConnection  *conn);
 gboolean              soup_server_connection_is_ssl                          (SoupServerConnection  *conn);
 void                  soup_server_connection_disconnect                      (SoupServerConnection  *conn);
 gboolean              soup_server_connection_is_connected                    (SoupServerConnection  *conn);
diff --git a/libsoup/server/soup-server-message-io.c b/libsoup/server/soup-server-message-io.c
new file mode 100644
index 00000000..44a8b4df
--- /dev/null
+++ b/libsoup/server/soup-server-message-io.c
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2022 Igalia S.L.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "soup-server-message-io.h"
+
+void
+soup_server_message_io_destroy (SoupServerMessageIO *io)
+{
+        if (!io)
+                return;
+
+        io->funcs->destroy (io);
+}
+
+void
+soup_server_message_io_finished (SoupServerMessageIO *io,
+                                 SoupServerMessage   *msg)
+{
+        io->funcs->finished (io, msg);
+}
+
+GIOStream *
+soup_server_message_io_steal (SoupServerMessageIO *io)
+{
+        return io->funcs->steal (io);
+}
+
+void
+soup_server_message_io_read_request (SoupServerMessageIO       *io,
+                                     SoupServerMessage         *msg,
+                                     SoupMessageIOCompletionFn  completion_cb,
+                                     gpointer                   user_data)
+{
+        io->funcs->read_request (io, msg, completion_cb, user_data);
+}
+
+void
+soup_server_message_io_pause (SoupServerMessageIO *io,
+                              SoupServerMessage   *msg)
+{
+        io->funcs->pause (io, msg);
+}
+
+void
+soup_server_message_io_unpause (SoupServerMessageIO *io,
+                                SoupServerMessage   *msg)
+{
+        io->funcs->unpause (io, msg);
+}
+
+gboolean
+soup_server_message_io_is_paused (SoupServerMessageIO *io,
+                                  SoupServerMessage   *msg)
+{
+        return io->funcs->is_paused (io, msg);
+}
diff --git a/libsoup/server/soup-server-message-io.h b/libsoup/server/soup-server-message-io.h
new file mode 100644
index 00000000..78b9c7d4
--- /dev/null
+++ b/libsoup/server/soup-server-message-io.h
@@ -0,0 +1,47 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2022 Igalia S.L.
+ */
+
+#pragma once
+
+#include "soup-server-message.h"
+#include "soup-message-io-completion.h"
+
+typedef struct _SoupServerMessageIO SoupServerMessageIO;
+
+typedef struct {
+        void       (*destroy)      (SoupServerMessageIO       *io);
+        void       (*finished)     (SoupServerMessageIO       *io,
+                                    SoupServerMessage         *msg);
+        GIOStream *(*steal)        (SoupServerMessageIO       *io);
+        void       (*read_request) (SoupServerMessageIO       *io,
+                                    SoupServerMessage         *msg,
+                                    SoupMessageIOCompletionFn  completion_cb,
+                                    gpointer                   user_data);
+        void       (*pause)        (SoupServerMessageIO       *io,
+                                    SoupServerMessage         *msg);
+        void       (*unpause)      (SoupServerMessageIO       *io,
+                                    SoupServerMessage         *msg);
+        gboolean   (*is_paused)    (SoupServerMessageIO       *io,
+                                    SoupServerMessage         *msg);
+} SoupServerMessageIOFuncs;
+
+struct _SoupServerMessageIO {
+        const SoupServerMessageIOFuncs *funcs;
+};
+
+void       soup_server_message_io_destroy      (SoupServerMessageIO       *io);
+void       soup_server_message_io_finished     (SoupServerMessageIO       *io,
+                                                SoupServerMessage         *msg);
+GIOStream *soup_server_message_io_steal        (SoupServerMessageIO       *io);
+void       soup_server_message_io_read_request (SoupServerMessageIO       *io,
+                                                SoupServerMessage         *msg,
+                                                SoupMessageIOCompletionFn  completion_cb,
+                                                gpointer                   user_data);
+void       soup_server_message_io_pause        (SoupServerMessageIO       *io,
+                                                SoupServerMessage         *msg);
+void       soup_server_message_io_unpause      (SoupServerMessageIO       *io,
+                                                SoupServerMessage         *msg);
+gboolean   soup_server_message_io_is_paused    (SoupServerMessageIO       *io,
+                                                SoupServerMessage         *msg);
diff --git a/libsoup/server/soup-server-message-private.h b/libsoup/server/soup-server-message-private.h
index 52fd8722..bb3b0fc4 100644
--- a/libsoup/server/soup-server-message-private.h
+++ b/libsoup/server/soup-server-message-private.h
@@ -20,11 +20,10 @@ void               soup_server_message_set_auth            (SoupServerMessage
                                                             SoupAuthDomain           *domain,
                                                             char                     *user);
 gboolean           soup_server_message_is_keepalive        (SoupServerMessage        *msg);
-GIOStream         *soup_server_message_io_steal            (SoupServerMessage        *msg);
-void               soup_server_message_io_pause            (SoupServerMessage        *msg);
-void               soup_server_message_io_unpause          (SoupServerMessage        *msg);
+void               soup_server_message_pause               (SoupServerMessage        *msg);
+void               soup_server_message_unpause             (SoupServerMessage        *msg);
 gboolean           soup_server_message_is_io_paused        (SoupServerMessage        *msg);
-void               soup_server_message_io_finished         (SoupServerMessage        *msg);
+void               soup_server_message_finish              (SoupServerMessage        *msg);
 void               soup_server_message_cleanup_response    (SoupServerMessage        *msg);
 void               soup_server_message_wrote_informational (SoupServerMessage        *msg);
 void               soup_server_message_wrote_headers       (SoupServerMessage        *msg);
@@ -44,14 +43,7 @@ void               soup_server_message_read_request        (SoupServerMessage
 void               soup_server_message_set_options_ping    (SoupServerMessage        *msg,
                                                             gboolean                  is_options_ping);
 
-typedef struct _SoupServerMessageIOData SoupServerMessageIOData;
-void                     soup_server_message_io_data_free  (SoupServerMessageIOData  *io);
-void                     soup_server_message_set_io_data   (SoupServerMessage        *msg,
-                                                            SoupServerMessageIOData  *io);
-SoupServerMessageIOData *soup_server_message_get_io_data   (SoupServerMessage        *msg);
-void                    soup_server_message_io_read_request(SoupServerMessageIOData  *io,
-                                                            SoupServerMessage        *msg,
-                                                            SoupMessageIOCompletionFn completion_cb,
-                                                            gpointer                  user_data);
+SoupServerMessageIO *soup_server_message_get_io_data       (SoupServerMessage        *msg);
+
 
 #endif /* __SOUP_SERVER_MESSAGE_PRIVATE_H__ */
diff --git a/libsoup/server/soup-server-message.c b/libsoup/server/soup-server-message.c
index bf81317a..d81d4722 100644
--- a/libsoup/server/soup-server-message.c
+++ b/libsoup/server/soup-server-message.c
@@ -58,7 +58,7 @@ struct _SoupServerMessage {
         SoupMessageBody    *response_body;
         SoupMessageHeaders *response_headers;
 
-        SoupServerMessageIOData *io_data;
+        SoupServerMessageIO *io_data;
 
         gboolean                 options_ping;
 
@@ -396,6 +396,7 @@ soup_server_message_class_init (SoupServerMessageClass *klass)
 static void
 connection_disconnected (SoupServerMessage *msg)
 {
+        msg->io_data = NULL;
         g_signal_emit (msg, signals[DISCONNECTED], 0);
 }
 
@@ -528,21 +529,45 @@ soup_server_message_read_request (SoupServerMessage        *msg,
                                   SoupMessageIOCompletionFn completion_cb,
                                   gpointer                  user_data)
 {
-        soup_server_message_set_io_data (msg, soup_server_connection_get_io_data (msg->conn));
+        msg->io_data = soup_server_connection_get_io_data (msg->conn);
         soup_server_message_io_read_request (msg->io_data, msg, completion_cb, user_data);
 }
 
+SoupServerMessageIO *
+soup_server_message_get_io_data (SoupServerMessage *msg)
+{
+        return msg->io_data;
+}
+
 void
-soup_server_message_set_io_data (SoupServerMessage       *msg,
-                                 SoupServerMessageIOData *io)
+soup_server_message_pause (SoupServerMessage *msg)
 {
-        msg->io_data = io;
+        g_return_if_fail (msg->io_data != NULL);
+
+        soup_server_message_io_pause (msg->io_data, msg);
 }
 
-SoupServerMessageIOData *
-soup_server_message_get_io_data (SoupServerMessage *msg)
+void
+soup_server_message_unpause (SoupServerMessage *msg)
 {
-        return msg->io_data;
+        g_return_if_fail (msg->io_data != NULL);
+
+        soup_server_message_io_unpause (msg->io_data, msg);
+}
+
+gboolean
+soup_server_message_is_io_paused (SoupServerMessage *msg)
+{
+        return msg->io_data && soup_server_message_io_is_paused (msg->io_data, msg);
+}
+
+void
+soup_server_message_finish (SoupServerMessage *msg)
+{
+        if (!msg->io_data)
+                return;
+
+        soup_server_message_io_finished (g_steal_pointer (&msg->io_data), msg);
 }
 
 void
@@ -1023,7 +1048,7 @@ soup_server_message_steal_connection (SoupServerMessage *msg)
         GIOStream *stream;
 
         g_object_ref (msg);
-        stream = soup_server_message_io_steal (msg);
+        stream = msg->io_data ? soup_server_message_io_steal (g_steal_pointer (&msg->io_data)) : NULL;
         if (stream) {
                 g_object_set_data_full (G_OBJECT (stream), "GSocket",
                                         soup_server_connection_steal_socket (msg->conn),
diff --git a/libsoup/server/soup-server.c b/libsoup/server/soup-server.c
index b0f948eb..99ea192b 100644
--- a/libsoup/server/soup-server.c
+++ b/libsoup/server/soup-server.c
@@ -993,9 +993,6 @@ client_disconnected (SoupServer        *server,
        SoupServerPrivate *priv = soup_server_get_instance_private (server);
 
        priv->clients = g_slist_remove (priv->clients, msg);
-
-       if (soup_server_message_get_status (msg) != 0)
-               soup_server_message_io_finished (msg);
 }
 
 typedef struct {
@@ -1915,7 +1912,8 @@ soup_server_pause_message (SoupServer        *server,
        g_return_if_fail (SOUP_IS_SERVER (server));
        g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg));
 
-       soup_server_message_io_pause (msg);
+        /* FIXME: make this public and deprecate soup_server_pause_message */
+       soup_server_message_pause (msg);
 }
 
 /**
@@ -1942,7 +1940,8 @@ soup_server_unpause_message (SoupServer        *server,
        g_return_if_fail (SOUP_IS_SERVER (server));
        g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg));
 
-       soup_server_message_io_unpause (msg);
+        /* FIXME: make this public and deprecate soup_server_unpause_message */
+       soup_server_message_unpause (msg);
 }
 
 /**


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