summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2022-07-07 15:00:06 +0200
committerCarlos Garcia Campos <cgarcia@igalia.com>2022-08-12 11:03:48 +0200
commit85ef40fe5af14a35622325edf298b2a901351cbb (patch)
tree921356a03f0c2ecce1ba9fa0d35821ff8ac7d501
parent675c06596271dd55404d9dcb15b86e0c95934b61 (diff)
downloadlibsoup-85ef40fe5af14a35622325edf298b2a901351cbb.tar.gz
server: add SoupServerMessageIO interface
-rw-r--r--libsoup/meson.build1
-rw-r--r--libsoup/server/http1/soup-server-message-io-http1.c186
-rw-r--r--libsoup/server/http1/soup-server-message-io-http1.h5
-rw-r--r--libsoup/server/soup-server-connection.c12
-rw-r--r--libsoup/server/soup-server-connection.h5
-rw-r--r--libsoup/server/soup-server-message-io.c62
-rw-r--r--libsoup/server/soup-server-message-io.h47
-rw-r--r--libsoup/server/soup-server-message-private.h18
-rw-r--r--libsoup/server/soup-server-message.c43
-rw-r--r--libsoup/server/soup-server.c9
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);
}
/**